diff --git a/.codeclimate.yml b/.codeclimate.yml index ed0f6f803..936294cd8 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -43,7 +43,7 @@ checks: plugins: rubocop: enabled: true - channel: rubocop-0-71 + channel: rubocop-0-86 brakeman: enabled: true eslint: diff --git a/.rubocop.yml b/.rubocop.yml index 65e4485ec..8137b729a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -69,6 +69,12 @@ Layout/EmptyLinesAroundAttributeAccessor: # Enabled: false # StyleGuide: '#heredoc-argument-closing-parentheses' +Layout/LineLength: + Description: 'Checks that line length does not exceed the configured limit.' + AutoCorrect: true # this is false by default + Exclude: + - docs/Gemfile + - Gemfile # Layout/MultilineArrayLineBreaks: # Description: >- diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index feed54828..50beb95f3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,13 +6,13 @@ require: # This configuration was generated by # `rubocop --auto-gen-config` -# on 2020-07-06 08:14:17 UTC using RuboCop version 0.86.0. +# on 2020-07-08 07:58:23 UTC using RuboCop version 0.86.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 279 +# Offense count: 278 # Configuration parameters: IgnoredMethods. Metrics/AbcSize: Max: 62 @@ -37,14 +37,16 @@ Performance/OpenStruct: - 'spec/models/github_repo_spec.rb' - 'spec/requests/github_repos_spec.rb' -# Offense count: 2 +# Offense count: 4 # Configuration parameters: Max. RSpec/ExampleLength: Exclude: + - 'spec/initializers/rack/attack_spec.rb' + - 'spec/liquid_tags/user_subscription_tag_spec.rb' - 'spec/models/comment_spec.rb' - 'spec/requests/display_ad_events_spec.rb' -# Offense count: 920 +# Offense count: 930 RSpec/MultipleExpectations: Max: 12 @@ -78,13 +80,12 @@ Rails/OutputSafety: - 'app/models/display_ad.rb' - 'app/models/message.rb' -# Offense count: 5 +# Offense count: 4 # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/UniqueValidationWithoutIndex: Exclude: - 'app/models/article.rb' - - 'app/models/follow.rb' # Offense count: 38 # Cop supports --auto-correct. @@ -99,10 +100,3 @@ Style/ClassAndModuleChildren: Style/SingleLineBlockParams: Exclude: - 'app/labor/markdown_fixer.rb' - -# Offense count: 555 -# Cop supports --auto-correct. -# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. -# URISchemes: http, https -Layout/LineLength: - Max: 308 diff --git a/app/black_box/black_box.rb b/app/black_box/black_box.rb index 7b6a4be64..480bac817 100644 --- a/app/black_box/black_box.rb +++ b/app/black_box/black_box.rb @@ -15,9 +15,16 @@ class BlackBox if article.decorate.cached_tag_list_array.include?("watercooler") reaction_points = (reaction_points * 0.8).to_i # watercooler posts shouldn't get as much love in feed end - function_caller.call("blackbox-production-articleHotness", - { article: article, user: article.user }.to_json).to_i + - reaction_points + recency_bonus + super_recent_bonus + super_super_recent_bonus + today_bonus + two_day_bonus + four_day_bonus + + article_hotness = function_caller.call( + "blackbox-production-articleHotness", + { article: article, user: article.user }.to_json, + ).to_i + + ( + article_hotness + reaction_points + recency_bonus + super_recent_bonus + + super_super_recent_bonus + today_bonus + two_day_bonus + four_day_bonus + ) end def comment_quality_score(comment) diff --git a/app/controllers/api/v0/analytics_controller.rb b/app/controllers/api/v0/analytics_controller.rb index 3493acbb0..4cb8715ea 100644 --- a/app/controllers/api/v0/analytics_controller.rb +++ b/app/controllers/api/v0/analytics_controller.rb @@ -63,7 +63,9 @@ module Api def validate_date_params raise ArgumentError, "Required 'start' parameter is missing" if analytics_params[:start].blank? - raise ArgumentError, "Date parameters 'start' or 'end' must be in the format of 'yyyy-mm-dd'" unless valid_date_params? + + message = "Date parameters 'start' or 'end' must be in the format of 'yyyy-mm-dd'" + raise ArgumentError, message unless valid_date_params? end def analytics_params diff --git a/app/controllers/api/v0/articles_controller.rb b/app/controllers/api/v0/articles_controller.rb index f2f948fff..47348cd74 100644 --- a/app/controllers/api/v0/articles_controller.rb +++ b/app/controllers/api/v0/articles_controller.rb @@ -117,8 +117,10 @@ module Api def allowed_to_change_org_id? potential_user = @article&.user || @user - if @article.nil? || OrganizationMembership.exists?(user: potential_user, organization_id: params.dig("article", "organization_id")) - OrganizationMembership.exists?(user: potential_user, organization_id: params.dig("article", "organization_id")) + if @article.nil? || OrganizationMembership.exists?(user: potential_user, + organization_id: params.dig("article", "organization_id")) + OrganizationMembership.exists?(user: potential_user, + organization_id: params.dig("article", "organization_id")) elsif potential_user == @user potential_user.org_admin?(params.dig("article", "organization_id")) || @user.any_admin? diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index f98afa51f..83bc4c129 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -267,8 +267,12 @@ class ArticlesController < ApplicationController if updated && @article.published && @article.saved_changes["published"] == [false, true] Notification.send_to_followers(@article, "Published") elsif @article.saved_changes["published"] == [true, false] - Notification.remove_all_by_action_without_delay(notifiable_ids: @article.id, notifiable_type: "Article", action: "Published") - Notification.remove_all(notifiable_ids: @article.comments.pluck(:id), notifiable_type: "Comment") if @article.comments.exists? + Notification.remove_all_by_action_without_delay(notifiable_ids: @article.id, notifiable_type: "Article", + action: "Published") + if @article.comments.exists? + Notification.remove_all(notifiable_ids: @article.comments.pluck(:id), + notifiable_type: "Comment") + end end end diff --git a/app/controllers/async_info_controller.rb b/app/controllers/async_info_controller.rb index 28184af76..a57959eb1 100644 --- a/app/controllers/async_info_controller.rb +++ b/app/controllers/async_info_controller.rb @@ -34,7 +34,8 @@ class AsyncInfoController < ApplicationController def shell_version set_surrogate_key_header "shell-version-endpoint" - # shell_version will change on every deploy. *Technically* could be only on changes to assets and shell, but this is more fool-proof. + # shell_version will change on every deploy. + # *Technically* could be only on changes to assets and shell, but this is more fool-proof. shell_version = ApplicationConfig["HEROKU_SLUG_COMMIT"] render json: { version: Rails.env.production? ? shell_version : rand(1000) }.to_json end @@ -57,7 +58,8 @@ class AsyncInfoController < ApplicationController name: @user.name, username: @user.username, profile_image_90: ProfileImage.new(@user).get(width: 90), - followed_tags: @user.cached_followed_tags.to_json(only: %i[id name bg_color_hex text_color_hex hotness_score], methods: [:points]), + followed_tags: @user.cached_followed_tags.to_json(only: %i[id name bg_color_hex text_color_hex hotness_score], + methods: [:points]), followed_podcast_ids: @user.cached_following_podcasts_ids, reading_list_ids: ReadingList.new(@user).cached_ids_of_articles, blocked_user_ids: @user.all_blocking.pluck(:blocked_id), diff --git a/app/controllers/chat_channel_memberships_controller.rb b/app/controllers/chat_channel_memberships_controller.rb index d05e2b9fd..b71764206 100644 --- a/app/controllers/chat_channel_memberships_controller.rb +++ b/app/controllers/chat_channel_memberships_controller.rb @@ -11,7 +11,8 @@ class ChatChannelMembershipsController < ApplicationController end def find_by_chat_channel_id - @membership = ChatChannelMembership.where(chat_channel_id: params[:chat_channel_id], user_id: current_user.id).first! + @membership = ChatChannelMembership.where(chat_channel_id: params[:chat_channel_id], + user_id: current_user.id).first! authorize @membership render json: @membership.to_json( only: %i[id status viewable_by chat_channel_id last_opened_at], @@ -32,7 +33,9 @@ class ChatChannelMembershipsController < ApplicationController def create_membership_request chat_channel = ChatChannel.find_by(id: channel_membership_request_params[:chat_channel_id]) authorize chat_channel, :update? - usernames = channel_membership_request_params[:invitation_usernames].split(",").map { |username| username.strip.delete("@") } + usernames = channel_membership_request_params[:invitation_usernames].split(",").map do |username| + username.strip.delete("@") + end users = User.where(username: usernames) invitations_sent = chat_channel.invite_users(users: users, membership_role: "member", inviter: current_user) message = if invitations_sent.zero? @@ -51,7 +54,8 @@ class ChatChannelMembershipsController < ApplicationController if existing_membership.present? && %w[active joining_request].exclude?(existing_membership.status) status = existing_membership.update(status: "joining_request", role: "member") else - membership = ChatChannelMembership.new(user_id: current_user.id, chat_channel_id: chat_channel.id, role: "member", status: "joining_request") + membership = ChatChannelMembership.new(user_id: current_user.id, chat_channel_id: chat_channel.id, + role: "member", status: "joining_request") status = membership.save end if status @@ -69,8 +73,14 @@ class ChatChannelMembershipsController < ApplicationController @chat_channel_membership.destroy message = "Invitation removed." else - send_chat_action_message("@#{current_user.username} removed @#{@chat_channel_membership.user.username} from #{@chat_channel_membership.channel_name}", current_user, @chat_channel_membership.chat_channel_id, "removed_from_channel") + membership = @chat_channel_membership + message = "@#{current_user.username} removed @#{membership.user.username} from #{membership.channel_name}" + send_chat_action_message( + message, current_user, @chat_channel_membership.chat_channel_id, "removed_from_channel" + ) + @chat_channel_membership.update(status: "removed_from_channel") + message = "Removed #{@chat_channel_membership.user.name}" end @@ -81,7 +91,10 @@ class ChatChannelMembershipsController < ApplicationController @chat_channel = ChatChannel.find(params[:chat_channel_id]) authorize @chat_channel, :update? @chat_channel_membership = @chat_channel.chat_channel_memberships.find(params[:membership_id]) - respond_to_invitation(@chat_channel_membership.status) if permitted_params[:user_action].present? && @chat_channel_membership.status == "joining_request" + + return unless permitted_params[:user_action].present? && @chat_channel_membership.status == "joining_request" + + respond_to_invitation(@chat_channel_membership.status) end def update @@ -95,7 +108,8 @@ class ChatChannelMembershipsController < ApplicationController authorize @chat_channel_membership @chat_channel_membership.update(permitted_params) if @chat_channel_membership.errors.any? - render json: { success: false, errors: @chat_channel_membership.errors.full_messages, message: "Failed to update settings." }, status: :bad_request + render json: { success: false, errors: @chat_channel_membership.errors.full_messages, + message: "Failed to update settings." }, status: :bad_request else render json: { success: true, message: "Personal settings updated." }, status: :ok end @@ -105,11 +119,13 @@ class ChatChannelMembershipsController < ApplicationController chat_channel_membership = ChatChannelMembership.find_by(id: params[:id]) authorize chat_channel_membership channel_name = chat_channel_membership.chat_channel.channel_name - send_chat_action_message("@#{current_user.username} left #{chat_channel_membership.channel_name}", current_user, chat_channel_membership.chat_channel_id, "left_channel") + send_chat_action_message("@#{current_user.username} left #{chat_channel_membership.channel_name}", current_user, + chat_channel_membership.chat_channel_id, "left_channel") chat_channel_membership.update(status: "left_channel") message = "You have left the channel #{channel_name}. It may take a moment to be removed from your list." if chat_channel_membership.errors.any? - render json: { success: false, message: "Failed to update membership", errors: chat_channel_membership.errors.full_messages }, status: :bad_request + render json: { success: false, message: "Failed to update membership", + errors: chat_channel_membership.errors.full_messages }, status: :bad_request else render json: { success: true, message: message }, status: :ok end @@ -129,6 +145,7 @@ class ChatChannelMembershipsController < ApplicationController if permitted_params[:user_action] == "accept" @chat_channel_membership.update(status: "active") channel_name = @chat_channel_membership.chat_channel.channel_name + if previous_status == "pending" send_chat_action_message( "@#{current_user.username} joined #{@chat_channel_membership.channel_name}", @@ -136,7 +153,8 @@ class ChatChannelMembershipsController < ApplicationController @chat_channel_membership.chat_channel_id, "joined", ) - flash[:settings_notice] = "Invitation to #{channel_name} accepted. It may take a moment to show up in your list." + + notice = "Invitation to #{channel_name} accepted. It may take a moment to show up in your list." else send_chat_action_message( "@#{current_user.username} added @#{@chat_channel_membership.user.username}", @@ -150,13 +168,16 @@ class ChatChannelMembershipsController < ApplicationController channel_invite_email. deliver_later - flash[:settings_notice] = "Accepted request of #{@chat_channel_membership.user.username} to join #{channel_name}." + notice = "Accepted request of #{@chat_channel_membership.user.username} to join #{channel_name}." end else @chat_channel_membership.update(status: "rejected") - flash[:settings_notice] = "Invitation rejected." + + notice = "Invitation rejected." end + flash[:settings_notice] = notice + membership_user = MembershipUserPresenter.new(@chat_channel_membership).as_json respond_to do |format| @@ -174,7 +195,8 @@ class ChatChannelMembershipsController < ApplicationController def send_chat_action_message(message, user, channel_id, action) temp_message_id = (0...20).map { ("a".."z").to_a[rand(8)] }.join - message = Message.create("message_markdown" => message, "user_id" => user.id, "chat_channel_id" => channel_id, "chat_action" => action) + message = Message.create("message_markdown" => message, "user_id" => user.id, "chat_channel_id" => channel_id, + "chat_action" => action) pusher_message_created(false, message, temp_message_id) end diff --git a/app/controllers/chat_channels_controller.rb b/app/controllers/chat_channels_controller.rb index 675e1de32..171aabdd8 100644 --- a/app/controllers/chat_channels_controller.rb +++ b/app/controllers/chat_channels_controller.rb @@ -23,7 +23,11 @@ class ChatChannelsController < ApplicationController end def show - @chat_messages = @chat_channel.messages.includes(:user).order("created_at DESC").offset(params[:message_offset]).limit(50) + @chat_messages = @chat_channel.messages. + includes(:user). + order(created_at: :desc). + offset(params[:message_offset]). + limit(50) end def create @@ -38,7 +42,8 @@ class ChatChannelsController < ApplicationController flash[:error] = chat_channel.errors.full_messages.to_sentence else if chat_channel_params[:discoverable].to_i.zero? - ChatChannelMembership.create(user_id: SiteConfig.mascot_user_id, chat_channel_id: chat_channel.id, role: "member", status: "active") + ChatChannelMembership.create(user_id: SiteConfig.mascot_user_id, chat_channel_id: chat_channel.id, + role: "member", status: "active") else ChatChannelMembership.find_by(user_id: SiteConfig.mascot_user_id)&.destroy end @@ -52,10 +57,12 @@ class ChatChannelsController < ApplicationController def update_channel chat_channel = ChatChannelUpdateService.perform(@chat_channel, chat_channel_params) if chat_channel.errors.any? - render json: { success: false, errors: chat_channel.errors.full_messages, message: "Channel settings updation failed. Try again later." }, success: :bad_request + render json: { success: false, errors: chat_channel.errors.full_messages, + message: "Channel settings updation failed. Try again later." }, success: :bad_request else if chat_channel_params[:discoverable] - ChatChannelMembership.create(user_id: SiteConfig.mascot_user_id, chat_channel_id: chat_channel.id, role: "member", status: "active") + ChatChannelMembership.create(user_id: SiteConfig.mascot_user_id, chat_channel_id: chat_channel.id, + role: "member", status: "active") else ChatChannelMembership.find_by(user_id: SiteConfig.mascot_user_id)&.destroy end @@ -162,10 +169,11 @@ class ChatChannelsController < ApplicationController def render_unopened_json_response @chat_channels_memberships = if session_current_user_id - ChatChannelMembership.where(user_id: session_current_user_id).includes(%i[chat_channel user]). + ChatChannelMembership.where(user_id: session_current_user_id). where(has_unopened_messages: true). where(show_global_badge_notification: true). where.not(status: %w[removed_from_channel left_channel]). + includes(%i[chat_channel user]). order("chat_channel_memberships.updated_at DESC") else [] @@ -187,14 +195,24 @@ class ChatChannelsController < ApplicationController def render_unopened_ids_response @unopened_ids = ChatChannelMembership.where(user_id: session_current_user_id).includes(:chat_channel). - where(has_unopened_messages: true).where.not(status: %w[removed_from_channel left_channel]).pluck(:chat_channel_id) + where(has_unopened_messages: true).where.not(status: %w[removed_from_channel + left_channel]).pluck(:chat_channel_id) render json: { unopened_ids: @unopened_ids } end def render_joining_request_json_response - requested_memberships_id = current_user.chat_channel_memberships.includes(:chat_channel). - where(chat_channels: { discoverable: true }, role: "mod").pluck(:chat_channel_id).map { |membership_id| ChatChannel.find_by(id: membership_id).requested_memberships }.flatten.map(&:id) - @chat_channels_memberships = ChatChannelMembership.includes(%i[user chat_channel]).where(id: requested_memberships_id) + requested_memberships_id = current_user. + chat_channel_memberships. + includes(:chat_channel). + where(chat_channels: { discoverable: true }, role: "mod"). + pluck(:chat_channel_id). + map { |membership_id| ChatChannel.find_by(id: membership_id).requested_memberships }. + flatten. + map(&:id) + + @chat_channels_memberships = ChatChannelMembership. + includes(%i[user chat_channel]). + where(id: requested_memberships_id) render "index.json" end @@ -227,6 +245,7 @@ class ChatChannelsController < ApplicationController else @chat_channel.adjusted_slug(current_user) end - Pusher.trigger("private-message-notifications-#{session_current_user_id}", "message-opened", { channel_type: @chat_channel.channel_type, adjusted_slug: adjusted_slug }.to_json) + Pusher.trigger("private-message-notifications-#{session_current_user_id}", "message-opened", + { channel_type: @chat_channel.channel_type, adjusted_slug: adjusted_slug }.to_json) end end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 57d838f9f..91798c404 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -239,7 +239,9 @@ class CommentsController < ApplicationController @comment.hidden_by_commentable_user = false if @comment.save @commentable = @comment&.commentable - @commentable&.update_column(:any_comments_hidden, @commentable.comments.pluck(:hidden_by_commentable_user).include?(true)) + @commentable&.update_columns( + any_comments_hidden: @commentable.comments.pluck(:hidden_by_commentable_user).include?(true), + ) render json: { hidden: "false" }, status: :ok else render json: { errors: @comment.errors_as_sentence, status: 422 }, status: :unprocessable_entity diff --git a/app/controllers/concerns/valid_request.rb b/app/controllers/concerns/valid_request.rb index e063955b0..da3ae446e 100644 --- a/app/controllers/concerns/valid_request.rb +++ b/app/controllers/concerns/valid_request.rb @@ -12,7 +12,8 @@ module ValidRequest if request.referer.present? request.referer.start_with?(URL.url) else - raise ::ActionController::InvalidAuthenticityToken, ::ApplicationController::NULL_ORIGIN_MESSAGE if request.origin == "null" + null_origin = request.origin == "null" + raise ::ActionController::InvalidAuthenticityToken, ::ApplicationController::NULL_ORIGIN_MESSAGE if null_origin request.origin.nil? || request.origin.gsub("https", "http") == request.base_url.gsub("https", "http") end diff --git a/app/controllers/email_authorizations_controller.rb b/app/controllers/email_authorizations_controller.rb index b98eda00e..ae71e0fec 100644 --- a/app/controllers/email_authorizations_controller.rb +++ b/app/controllers/email_authorizations_controller.rb @@ -6,7 +6,8 @@ class EmailAuthorizationsController < ApplicationController raise ActionController::RoutingError, "Not Found" unless current_user == user email_authorization = user.email_authorizations.order("created_at DESC").first - raise ActionController::RoutingError, "Not Found" unless email_authorization.confirmation_token == params[:confirmation_token] + correct_token = email_authorization.confirmation_token == params[:confirmation_token] + raise ActionController::RoutingError, "Not Found" unless correct_token email_authorization.update(verified_at: Time.current) redirect_to root_path diff --git a/app/controllers/follows_controller.rb b/app/controllers/follows_controller.rb index d123f9d38..02c7d5334 100644 --- a/app/controllers/follows_controller.rb +++ b/app/controllers/follows_controller.rb @@ -14,7 +14,8 @@ class FollowsController < ApplicationController return render plain: following_them_check unless params[:followable_type] == "User" - following_you_check = FollowChecker.new(User.find_by(id: params[:id]), params[:followable_type], current_user.id).cached_follow_check + following_you_check = FollowChecker.new(User.find_by(id: params[:id]), params[:followable_type], + current_user.id).cached_follow_check if following_them_check && following_you_check render plain: "mutual" @@ -34,7 +35,8 @@ class FollowsController < ApplicationController "self" else following_them_check = FollowChecker.new(current_user, params[:followable_type], id).cached_follow_check - following_you_check = FollowChecker.new(User.find_by(id: id), params[:followable_type], current_user.id).cached_follow_check + following_you_check = FollowChecker.new(User.find_by(id: id), params[:followable_type], + current_user.id).cached_follow_check if following_them_check && following_you_check "mutual" elsif following_you_check diff --git a/app/controllers/html_variants_controller.rb b/app/controllers/html_variants_controller.rb index 1110e7c6f..66c07b8b2 100644 --- a/app/controllers/html_variants_controller.rb +++ b/app/controllers/html_variants_controller.rb @@ -3,15 +3,18 @@ class HtmlVariantsController < ApplicationController def index authorize HtmlVariant - @html_variants = if params[:state] == "mine" - current_user.html_variants.order("created_at DESC").includes(:user).page(params[:page]).per(30) - elsif params[:state] == "admin" - HtmlVariant.where(published: true, approved: false).order("created_at DESC").includes(:user).page(params[:page]).per(30) - elsif params[:state].present? - HtmlVariant.where(published: true, approved: true, group: params[:state]).order("success_rate DESC").includes(:user).page(params[:page]).per(30) - else - HtmlVariant.where(published: true, approved: true).order("success_rate DESC").includes(:user).page(params[:page]).per(30) - end + + relation = if params[:state] == "mine" + current_user.html_variants.order(created_at: :desc) + elsif params[:state] == "admin" + HtmlVariant.where(published: true, approved: false).order(created_at: :desc) + elsif params[:state].present? + HtmlVariant.where(published: true, approved: true, group: params[:state]).order(success_rate: :desc) + else + HtmlVariant.where(published: true, approved: true).order(success_rate: :desc) + end + + @html_variants = relation.includes(:user).page(params[:page]).per(30) end def new diff --git a/app/controllers/internal/articles_controller.rb b/app/controllers/internal/articles_controller.rb index 3b5376a39..83faf9c5e 100644 --- a/app/controllers/internal/articles_controller.rb +++ b/app/controllers/internal/articles_controller.rb @@ -7,7 +7,9 @@ class Internal::ArticlesController < Internal::ApplicationController def index @pending_buffer_updates = BufferUpdate.where(status: "pending").includes(:article) - @user_buffer_updates = BufferUpdate.where(status: "sent_direct", approver_user_id: current_user.id).where("created_at > ?", 24.hours.ago) + @user_buffer_updates = BufferUpdate.where(status: "sent_direct", approver_user_id: current_user.id).where( + "created_at > ?", 24.hours.ago + ) case params[:state] when /not-buffered/ diff --git a/app/controllers/internal/configs_controller.rb b/app/controllers/internal/configs_controller.rb index 812e10173..af2eb9094 100644 --- a/app/controllers/internal/configs_controller.rb +++ b/app/controllers/internal/configs_controller.rb @@ -45,7 +45,8 @@ class Internal::ConfigsController < Internal::ApplicationController onboarding_params | job_params - params[:site_config][:email_addresses][:default] = ApplicationConfig["DEFAULT_EMAIL"] if params[:site_config][:email_addresses].present? + has_emails = params[:site_config][:email_addresses].present? + params[:site_config][:email_addresses][:default] = ApplicationConfig["DEFAULT_EMAIL"] if has_emails params.require(:site_config).permit( allowed_params, authentication_providers: [], @@ -57,7 +58,8 @@ class Internal::ConfigsController < Internal::ApplicationController def extra_authorization_and_confirmation not_authorized unless current_user.has_role?(:single_resource_admin, Config) # Special additional permission - not_authorized if params[:confirmation] != "My username is @#{current_user.username} and this action is 100% safe and appropriate." + confirmation_message = "My username is @#{current_user.username} and this action is 100% safe and appropriate." + not_authorized if params[:confirmation] != confirmation_message end def clean_up_params diff --git a/app/controllers/internal/organization_memberships_controller.rb b/app/controllers/internal/organization_memberships_controller.rb index 61cda8f6e..75e605a35 100644 --- a/app/controllers/internal/organization_memberships_controller.rb +++ b/app/controllers/internal/organization_memberships_controller.rb @@ -17,7 +17,8 @@ class Internal::OrganizationMembershipsController < Internal::ApplicationControl if organization && organization_membership.save flash[:success] = "User was successfully added to #{organization.name}" elsif organization.blank? - flash[:danger] = "Organization ##{organization_membership_params[:organization_id]} does not exist. Perhaps a typo?" + message = "Organization ##{organization_membership_params[:organization_id]} does not exist. Perhaps a typo?" + flash[:danger] = message else flash[:danger] = organization_membership.errors.full_messages end @@ -29,7 +30,8 @@ class Internal::OrganizationMembershipsController < Internal::ApplicationControl if organization_membership.destroy flash[:success] = "User was successfully removed from org ##{organization_membership.organization_id}" else - flash[:danger] = "Something went wrong with removing the user from org ##{organization_membership.organization_id}" + message = "Something went wrong with removing the user from org ##{organization_membership.organization_id}" + flash[:danger] = message end redirect_to internal_user_path(organization_membership.user_id) end diff --git a/app/controllers/internal/pages_controller.rb b/app/controllers/internal/pages_controller.rb index 56a93163d..b24fcfdef 100644 --- a/app/controllers/internal/pages_controller.rb +++ b/app/controllers/internal/pages_controller.rb @@ -34,7 +34,8 @@ class Internal::PagesController < Internal::ApplicationController private def page_params - allowed_params = %i[title slug body_markdown body_html body_json description template is_top_level_path social_image] + allowed_params = %i[title slug body_markdown body_html body_json description template is_top_level_path + social_image] params.require(:page).permit(allowed_params) end end diff --git a/app/controllers/internal/permissions_controller.rb b/app/controllers/internal/permissions_controller.rb index 15d4ffb80..63cc8025a 100644 --- a/app/controllers/internal/permissions_controller.rb +++ b/app/controllers/internal/permissions_controller.rb @@ -2,6 +2,10 @@ class Internal::PermissionsController < Internal::ApplicationController layout "internal" def index - @users = User.with_role(:admin).union(User.with_role(:super_admin)).union(User.with_role(:single_resource_admin, :any)).page(params[:page]).per(50) + @users = User.with_role(:admin). + union(User.with_role(:super_admin)). + union(User.with_role(:single_resource_admin, :any)). + page(params[:page]). + per(50) end end diff --git a/app/controllers/internal/podcasts_controller.rb b/app/controllers/internal/podcasts_controller.rb index 77cc5548f..8f87ef837 100644 --- a/app/controllers/internal/podcasts_controller.rb +++ b/app/controllers/internal/podcasts_controller.rb @@ -9,7 +9,10 @@ class Internal::PodcastsController < Internal::ApplicationController select("podcasts.*, count(podcast_episodes) as episodes_count"). group("podcasts.id").order("podcasts.created_at DESC"). page(params[:page]).per(50) - @podcasts = @podcasts.where("podcasts.title ILIKE :search", search: "%#{params[:search]}%") if params[:search].present? + + return if params[:search].blank? + + @podcasts = @podcasts.where("podcasts.title ILIKE :search", search: "%#{params[:search]}%") end def edit; end diff --git a/app/controllers/internal/sponsorships_controller.rb b/app/controllers/internal/sponsorships_controller.rb index 71a3ed4af..841322725 100644 --- a/app/controllers/internal/sponsorships_controller.rb +++ b/app/controllers/internal/sponsorships_controller.rb @@ -33,6 +33,7 @@ class Internal::SponsorshipsController < Internal::ApplicationController private def sponsorship_params - params.require(:sponsorship).permit(%i[status expires_at tagline url blurb_html featured_number instructions instructions_updated_at]) + params.require(:sponsorship).permit(%i[status expires_at tagline url blurb_html featured_number instructions + instructions_updated_at]) end end diff --git a/app/controllers/internal/tools_controller.rb b/app/controllers/internal/tools_controller.rb index 0d0759a2f..f46115032 100644 --- a/app/controllers/internal/tools_controller.rb +++ b/app/controllers/internal/tools_controller.rb @@ -39,7 +39,10 @@ class Internal::ToolsController < Internal::ApplicationController end def bust_link(link) - link.sub!("https://#{ApplicationConfig['APP_DOMAIN']}", "") if link.starts_with?("https://#{ApplicationConfig['APP_DOMAIN']}") + if link.starts_with?("https://#{ApplicationConfig['APP_DOMAIN']}") + link.sub!("https://#{ApplicationConfig['APP_DOMAIN']}", + "") + end CacheBuster.bust(link) CacheBuster.bust("#{link}/") CacheBuster.bust("#{link}?i=i") diff --git a/app/controllers/internal/users_controller.rb b/app/controllers/internal/users_controller.rb index d8f474f63..ba915df8a 100644 --- a/app/controllers/internal/users_controller.rb +++ b/app/controllers/internal/users_controller.rb @@ -24,7 +24,9 @@ class Internal::UsersController < Internal::ApplicationController joins(:organization). order("organizations.name ASC"). includes(:organization) - @last_email_verification_date = @user.email_authorizations.where.not(verified_at: nil).order("created_at DESC").first&.verified_at || "Never" + @last_email_verification_date = @user.email_authorizations. + where.not(verified_at: nil). + order("created_at DESC").first&.verified_at || "Never" end def update @@ -55,7 +57,10 @@ class Internal::UsersController < Internal::ApplicationController @user = User.find(params[:id]) begin Moderator::DeleteUser.call(admin: current_user, user: @user, user_params: user_params) - flash[:success] = "@#{@user.username} (email: #{@user.email.presence || 'no email'}, user_id: #{@user.id}) has been fully deleted. If requested, old content may have been ghostified. If this is a GDPR delete, delete them from Mailchimp & Google Analytics." + message = "@#{@user.username} (email: #{@user.email.presence || 'no email'}, user_id: #{@user.id}) " \ + "has been fully deleted. If requested, old content may have been ghostified. " \ + "If this is a GDPR delete, delete them from Mailchimp & Google Analytics." + flash[:success] = message rescue StandardError => e flash[:danger] = e.message end diff --git a/app/controllers/listings_controller.rb b/app/controllers/listings_controller.rb index 889aaa428..df000e03a 100644 --- a/app/controllers/listings_controller.rb +++ b/app/controllers/listings_controller.rb @@ -13,7 +13,8 @@ class ListingsController < ApplicationController DASHBOARD_JSON_OPTIONS = { only: %i[ - title tag_list created_at expires_at bumped_at updated_at category id user_id slug organization_id location published + title tag_list created_at expires_at bumped_at updated_at category id + user_id slug organization_id location published ], include: { author: { only: %i[username name], methods: %i[username profile_image_90] } diff --git a/app/controllers/moderations_controller.rb b/app/controllers/moderations_controller.rb index d313bf2b1..9d534163d 100644 --- a/app/controllers/moderations_controller.rb +++ b/app/controllers/moderations_controller.rb @@ -16,7 +16,10 @@ class ModerationsController < ApplicationController where("score > -5 AND score < 5"). order("published_at DESC").limit(70) articles = articles.cached_tagged_with(params[:tag]) if params[:tag].present? - articles = articles.where("nth_published_by_author > 0 AND nth_published_by_author < 4 AND published_at > ?", 7.days.ago) if params[:state] == "new-authors" + if params[:state] == "new-authors" + articles = articles.where("nth_published_by_author > 0 AND nth_published_by_author < 4 AND published_at > ?", + 7.days.ago) + end @articles = articles.includes(:user).to_json(JSON_OPTIONS) @tag = Tag.find_by(name: params[:tag]) || not_found if params[:tag].present? @current_user_tags = current_user.moderator_for_tags @@ -41,7 +44,9 @@ class ModerationsController < ApplicationController has_no_relevant_adjustments = @adjustments.pluck(:tag_id).intersection(tag_mod_tag_ids).size.zero? can_be_adjusted = @moderatable.tags.pluck(:id).intersection(tag_mod_tag_ids).size.positive? - @should_show_adjust_tags = tag_mod_tag_ids.size.positive? && ((has_room_for_tags && has_no_relevant_adjustments) || (!has_room_for_tags && has_no_relevant_adjustments && can_be_adjusted)) + @should_show_adjust_tags = tag_mod_tag_ids.size.positive? && + ((has_room_for_tags && has_no_relevant_adjustments) || + (!has_room_for_tags && has_no_relevant_adjustments && can_be_adjusted)) render template: "moderations/actions_panel" end @@ -50,13 +55,15 @@ class ModerationsController < ApplicationController def load_article authorize(User, :moderation_routes?) + @tag_adjustment = TagAdjustment.new @moderatable = Article.find_by(slug: params[:slug]) not_found unless @moderatable @tag_moderator_tags = Tag.with_role(:tag_moderator, current_user) @adjustments = TagAdjustment.where(article_id: @moderatable.id) @already_adjusted_tags = @adjustments.map(&:tag_name).join(", ") - @allowed_to_adjust = @moderatable.class.name == "Article" && (current_user.has_role?(:super_admin) || @tag_moderator_tags.any?) + @allowed_to_adjust = @moderatable.class.name == "Article" && ( + current_user.has_role?(:super_admin) || @tag_moderator_tags.any?) @hidden_comments = @moderatable.comments.where(hidden_by_commentable_user: true) end end diff --git a/app/controllers/notification_subscriptions_controller.rb b/app/controllers/notification_subscriptions_controller.rb index 7a63f29ba..e2c804b01 100644 --- a/app/controllers/notification_subscriptions_controller.rb +++ b/app/controllers/notification_subscriptions_controller.rb @@ -1,7 +1,8 @@ class NotificationSubscriptionsController < ApplicationController def show result = if current_user - NotificationSubscription.where(user_id: current_user.id, notifiable_id: params[:notifiable_id], notifiable_type: params[:notifiable_type]). + NotificationSubscription.where(user_id: current_user.id, notifiable_id: params[:notifiable_id], + notifiable_type: params[:notifiable_type]). first&.to_json(only: %i[config]) || { config: "not_subscribed" } end respond_to do |format| @@ -12,9 +13,12 @@ class NotificationSubscriptionsController < ApplicationController def upsert not_found unless current_user - @notification_subscription = NotificationSubscription.find_or_initialize_by(user_id: current_user.id, - notifiable_id: params[:notifiable_id], - notifiable_type: params[:notifiable_type].capitalize) + @notification_subscription = NotificationSubscription.find_or_initialize_by( + user_id: current_user.id, + notifiable_id: params[:notifiable_id], + notifiable_type: params[:notifiable_type].capitalize, + ) + if params[:config] == "not_subscribed" @notification_subscription.delete @notification_subscription.notifiable.update(receive_notifications: false) if current_user_is_author? @@ -24,9 +28,9 @@ class NotificationSubscriptionsController < ApplicationController @notification_subscription.notifiable.update(receive_notifications: true) if receive_notifications @notification_subscription.save end - result = @notification_subscription.persisted? + respond_to do |format| - format.json { render json: result } + format.json { render json: @notification_subscription.persisted? } format.html { redirect_to request.referer } end end diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 0e1bad14f..b20a3b62b 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -17,7 +17,8 @@ class OrganizationsController < ApplicationController authorize @organization if @organization.save rate_limiter.track_limit_by_action(:organization_creation) - @organization_membership = OrganizationMembership.create!(organization_id: @organization.id, user_id: current_user.id, type_of_user: "admin") + @organization_membership = OrganizationMembership.create!(organization_id: @organization.id, + user_id: current_user.id, type_of_user: "admin") flash[:settings_notice] = "Your organization was successfully created and you are an admin." redirect_to "/settings/organization/#{@organization.id}" else @@ -41,7 +42,8 @@ class OrganizationsController < ApplicationController redirect_to "/settings/organization" else @org_organization_memberships = @organization.organization_memberships.includes(:user) - @organization_membership = OrganizationMembership.find_by(user_id: current_user.id, organization_id: @organization.id) + @organization_membership = OrganizationMembership.find_by(user_id: current_user.id, + organization_id: @organization.id) render template: "users/edit" end diff --git a/app/controllers/page_views_controller.rb b/app/controllers/page_views_controller.rb index 9f9185f35..19f8e1b2c 100644 --- a/app/controllers/page_views_controller.rb +++ b/app/controllers/page_views_controller.rb @@ -1,5 +1,6 @@ class PageViewsController < ApplicationMetalController - # ApplicationMetalController because we do not need all bells and whistles of ApplicationController, so should help performance. + # ApplicationMetalController because we do not need all bells and whistles of ApplicationController. + # It should help performance. include ActionController::Head def create @@ -18,7 +19,8 @@ class PageViewsController < ApplicationMetalController def update if session_current_user_id - page_view = PageView.order("created_at DESC").find_or_create_by(article_id: params[:id], user_id: session_current_user_id) + page_view = PageView.order("created_at DESC").find_or_create_by(article_id: params[:id], + user_id: session_current_user_id) unless page_view.new_record? page_view.update_column(:time_tracked_in_seconds, page_view.time_tracked_in_seconds + 15) end @@ -49,7 +51,10 @@ class PageViewsController < ApplicationMetalController page_views_from_google_com = @article.page_views.where(referrer: "https://www.google.com/") organic_count = page_views_from_google_com.sum(:counts_for_number_of_views) - @article.update_column(:organic_page_views_count, organic_count) if organic_count > @article.organic_page_views_count + if organic_count > @article.organic_page_views_count + @article.update_column(:organic_page_views_count, + organic_count) + end organic_count_past_week_count = page_views_from_google_com. where("created_at > ?", 1.week.ago).sum(:counts_for_number_of_views) diff --git a/app/controllers/poll_votes_controller.rb b/app/controllers/poll_votes_controller.rb index 9a0100962..9041be468 100644 --- a/app/controllers/poll_votes_controller.rb +++ b/app/controllers/poll_votes_controller.rb @@ -13,7 +13,8 @@ class PollVotesController < ApplicationController def create @poll_option = PollOption.find(poll_vote_params[:poll_option_id]) - @poll_vote = PollVote.create(poll_option_id: @poll_option&.id, user_id: current_user.id, poll_id: @poll_option.poll_id) + @poll_vote = PollVote.create(poll_option_id: @poll_option&.id, user_id: current_user.id, + poll_id: @poll_option.poll_id) @poll = @poll_option.reload.poll render json: { voting_data: @poll.voting_data, poll_id: @poll.id, diff --git a/app/controllers/rating_votes_controller.rb b/app/controllers/rating_votes_controller.rb index ba6edd4e2..9a7fb7069 100644 --- a/app/controllers/rating_votes_controller.rb +++ b/app/controllers/rating_votes_controller.rb @@ -6,7 +6,8 @@ class RatingVotesController < ApplicationController def create authorize RatingVote - rating_vote = RatingVote.where(user_id: current_user.id, article_id: rating_vote_params[:article_id]).first || RatingVote.new + rating_vote = RatingVote.where(user_id: current_user.id, + article_id: rating_vote_params[:article_id]).first || RatingVote.new rating_vote.user_id = current_user.id rating_vote.article_id = rating_vote_params[:article_id] rating_vote.rating = rating_vote_params[:rating].to_f @@ -18,7 +19,9 @@ class RatingVotesController < ApplicationController end else respond_to do |format| - format.json { render json: { error: rating_vote.errors.full_messages.to_sentence }, status: :unprocessable_entity } + format.json do + render json: { error: rating_vote.errors.full_messages.to_sentence }, status: :unprocessable_entity + end format.html { render json: { result: "Not Upserted Successfully" } } end end diff --git a/app/controllers/reactions_controller.rb b/app/controllers/reactions_controller.rb index 430497174..3ba7cba2a 100644 --- a/app/controllers/reactions_controller.rb +++ b/app/controllers/reactions_controller.rb @@ -83,7 +83,10 @@ class ReactionsController < ApplicationController Moderator::SinkArticles.call(reaction.reactable_id) if reaction.vomit_on_user? Notification.send_reaction_notification(reaction, reaction.target_user) - Notification.send_reaction_notification(reaction, reaction.reactable.organization) if reaction.reaction_on_organization_article? + if reaction.reaction_on_organization_article? + Notification.send_reaction_notification(reaction, + reaction.reactable.organization) + end result = "create" @@ -103,7 +106,8 @@ class ReactionsController < ApplicationController end def cached_user_public_comment_reactions(user, comment_ids) - cache = Rails.cache.fetch("cached-user-#{user.id}-reaction-ids-#{user.public_reactions_count}", expires_in: 24.hours) do + cache = Rails.cache.fetch("cached-user-#{user.id}-reaction-ids-#{user.public_reactions_count}", + expires_in: 24.hours) do user.reactions.public_category.where(reactable_type: "Comment").each_with_object({}) do |r, h| h[r.reactable_id] = r.attributes end @@ -128,7 +132,10 @@ class ReactionsController < ApplicationController reaction.destroy Moderator::SinkArticles.call(reaction.reactable_id) if reaction.vomit_on_user? Notification.send_reaction_notification_without_delay(reaction, reaction.target_user) - Notification.send_reaction_notification_without_delay(reaction, reaction.reactable.organization) if reaction.reaction_on_organization_article? + if reaction.reaction_on_organization_article? + Notification.send_reaction_notification_without_delay(reaction, + reaction.reactable.organization) + end "destroy" end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 5c3ab6627..a885961d4 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -57,7 +57,11 @@ class SearchController < ApplicationController end def chat_channels - search_user_id = chat_channel_params[:user_id].present? ? [current_user.id, SiteConfig.mascot_user_id] : [current_user.id] + search_user_id = if chat_channel_params[:user_id].present? + [current_user.id, SiteConfig.mascot_user_id] + else + [current_user.id] + end ccm_docs = Search::ChatChannelMembership.search_documents( params: chat_channel_params.merge(user_id: search_user_id).to_h, ) diff --git a/app/controllers/sitemaps_controller.rb b/app/controllers/sitemaps_controller.rb index 68bc3111b..578696693 100644 --- a/app/controllers/sitemaps_controller.rb +++ b/app/controllers/sitemaps_controller.rb @@ -11,7 +11,11 @@ class SitemapsController < ApplicationController rescue ArgumentError not_found end - @articles = Article.published.where("published_at > ? AND published_at < ? AND score > ?", date, date.end_of_month, 3).pluck(:path, :last_comment_at) + + @articles = Article.published. + where("published_at > ? AND published_at < ? AND score > ?", date, date.end_of_month, 3). + pluck(:path, :last_comment_at) + set_surrogate_controls(date) set_cache_control_headers(@max_age, stale_while_revalidate: @stale_while_revalidate, diff --git a/app/controllers/social_previews_controller.rb b/app/controllers/social_previews_controller.rb index a0d94009a..2324ede0b 100644 --- a/app/controllers/social_previews_controller.rb +++ b/app/controllers/social_previews_controller.rb @@ -44,7 +44,9 @@ class SocialPreviewsController < ApplicationController def comment @comment = Comment.find(params[:id]) - @tag_badges = Badge.where(id: Tag.where(name: @comment.commentable&.decorate&.cached_tag_list_array).pluck(:badge_id)) + + badge_ids = Tag.where(name: @comment.commentable&.decorate&.cached_tag_list_array).pluck(:badge_id) + @tag_badges = Badge.where(id: badge_ids) set_respond end @@ -58,7 +60,8 @@ class SocialPreviewsController < ApplicationController end format.png do html = render_to_string(template, formats: :html, layout: false) - redirect_to HtmlCssToImage.fetch_url(html: html, css: PNG_CSS, google_fonts: "Roboto|Roboto+Condensed"), status: :found + redirect_to HtmlCssToImage.fetch_url(html: html, css: PNG_CSS, + google_fonts: "Roboto|Roboto+Condensed"), status: :found end end end diff --git a/app/controllers/stories/feeds_controller.rb b/app/controllers/stories/feeds_controller.rb index b88d67ae8..e249fbf13 100644 --- a/app/controllers/stories/feeds_controller.rb +++ b/app/controllers/stories/feeds_controller.rb @@ -9,10 +9,13 @@ class Stories::FeedsController < ApplicationController "more_comments_experiment" => :more_comments_experiment, "more_experience_level_weight_experiment" => :more_experience_level_weight_experiment, "more_tag_weight_randomized_at_end_experiment" => :more_tag_weight_randomized_at_end_experiment, - "more_experience_level_weight_randomized_at_end_experiment" => :more_experience_level_weight_randomized_at_end_experiment, + "more_experience_level_weight_randomized_at_end_experiment" => + :more_experience_level_weight_randomized_at_end_experiment, "more_comments_randomized_at_end_experiment" => :more_comments_randomized_at_end_experiment, - "more_comments_medium_weight_randomized_at_end_experiment" => :more_comments_medium_weight_randomized_at_end_experiment, - "more_comments_minimal_weight_randomized_at_end_experiment" => :more_comments_minimal_weight_randomized_at_end_experiment, + "more_comments_medium_weight_randomized_at_end_experiment" => + :more_comments_medium_weight_randomized_at_end_experiment, + "more_comments_minimal_weight_randomized_at_end_experiment" => + :more_comments_minimal_weight_randomized_at_end_experiment, "mix_of_everything_experiment" => :mix_of_everything_experiment }.freeze diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index a5e14ce89..0d02e5741 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -72,7 +72,10 @@ class StoriesController < ApplicationController campaign_articles_scope = Article.tagged_with(SiteConfig.campaign_featured_tags, any: true). where("published_at > ? AND score > ?", 4.weeks.ago, 0). order("hotness_score DESC") - campaign_articles_scope = campaign_articles_scope.where(approved: true) if SiteConfig.campaign_articles_require_approval? + + requires_approval = SiteConfig.campaign_articles_require_approval? + campaign_articles_scope = campaign_articles_scope.where(approved: true) if requires_approval + @campaign_articles_count = campaign_articles_scope.count @latest_campaign_articles = campaign_articles_scope.limit(5).pluck(:path, :title, :comments_count, :created_at) end diff --git a/app/controllers/tag_adjustments_controller.rb b/app/controllers/tag_adjustments_controller.rb index ff6d59b0c..50953f8f3 100644 --- a/app/controllers/tag_adjustments_controller.rb +++ b/app/controllers/tag_adjustments_controller.rb @@ -19,7 +19,10 @@ class TagAdjustmentsController < ApplicationController service.update_tags_and_notify tag = tag_adjustment.tag respond_to do |format| - format.json { render json: { status: "Success", result: tag_adjustment.adjustment_type, colors: { bg: tag.bg_color_hex, text: tag.text_color_hex } } } + format.json do + render json: { status: "Success", result: tag_adjustment.adjustment_type, + colors: { bg: tag.bg_color_hex, text: tag.text_color_hex } } + end format.html { redirect_to "#{URI.parse(article.path).path}/mod" } end else @@ -40,11 +43,18 @@ class TagAdjustmentsController < ApplicationController def destroy authorize User, :moderation_routes? - tag_adjustment = TagAdjustment.find(params[:id]) - tag_adjustment.destroy - @article = Article.find(tag_adjustment.article_id) - @article.update!(tag_list: @article.tag_list.add(tag_adjustment.tag_name)) if tag_adjustment.adjustment_type == "removal" - @article.update!(tag_list: @article.tag_list.remove(tag_adjustment.tag_name)) if tag_adjustment.adjustment_type == "addition" + + adjustment = TagAdjustment.find(params[:id]) + adjustment.destroy + + @article = Article.find(adjustment.article_id) + + removal_type = adjustment.adjustment_type == "removal" + @article.update!(tag_list: @article.tag_list.add(adjustment.tag_name)) if removal_type + + addition_type = adjustment.adjustment_type == "addition" + @article.update!(tag_list: @article.tag_list.remove(adjustment.tag_name)) if addition_type + respond_to do |format| # TODO: add tag adjustment removal async route in actions panel format.json { render json: { result: "Tag adjustment destroyed" } } diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 782d6174f..8216a24f7 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -93,11 +93,13 @@ class UsersController < ApplicationController set_tabs("account") if destroy_request_in_progress? - flash[:settings_notice] = "You have already requested account deletion. Please, check your email for further instructions." + notice = "You have already requested account deletion. Please, check your email for further instructions." + flash[:settings_notice] = notice redirect_to user_settings_path(@tab) elsif @user.email? Users::RequestDestroy.call(@user) - flash[:settings_notice] = "You have requested account deletion. Please, check your email for further instructions." + notice = "You have requested account deletion. Please, check your email for further instructions." + flash[:settings_notice] = notice redirect_to user_settings_path(@tab) else flash[:settings_notice] = "Please, provide an email to delete your account." @@ -204,7 +206,8 @@ class UsersController < ApplicationController adminable = User.find(params[:user_id]) org = Organization.find_by(id: params[:organization_id]) - not_authorized unless current_user.org_admin?(org) && OrganizationMembership.exists?(user: adminable, organization: org) + not_authorized unless current_user.org_admin?(org) && OrganizationMembership.exists?(user: adminable, + organization: org) OrganizationMembership.find_by(user_id: adminable.id, organization_id: org.id).update(type_of_user: "admin") flash[:settings_notice] = "#{adminable.name} is now an admin." @@ -306,7 +309,8 @@ class UsersController < ApplicationController authorize @organization, :part_of_org? @org_organization_memberships = @organization.organization_memberships.includes(:user) - @organization_membership = OrganizationMembership.find_by(user_id: current_user.id, organization_id: @organization.id) + @organization_membership = OrganizationMembership.find_by(user_id: current_user.id, + organization_id: @organization.id) end end diff --git a/app/helpers/articles_helper.rb b/app/helpers/articles_helper.rb index 6ae898fc6..3cddec25a 100644 --- a/app/helpers/articles_helper.rb +++ b/app/helpers/articles_helper.rb @@ -12,7 +12,9 @@ module ArticlesHelper def has_vid?(article) return if article.processed_html.blank? - article.processed_html.include?("youtube.com/embed/") || article.processed_html.include?("player.vimeo.com") || article.comments_blob.include?("youtube") + article.processed_html.include?("youtube.com/embed/") || + article.processed_html.include?("player.vimeo.com") || + article.comments_blob.include?("youtube") end def collection_link_class(current_article, linked_article) diff --git a/app/labor/assign_tag_moderator.rb b/app/labor/assign_tag_moderator.rb index 18a996b55..23674d024 100644 --- a/app/labor/assign_tag_moderator.rb +++ b/app/labor/assign_tag_moderator.rb @@ -25,9 +25,12 @@ module AssignTagModerator end def self.add_to_chat_channels(user, tag) - ChatChannel.find_by(slug: "tag-moderators").add_users(user) if user.chat_channels.where(slug: "tag-moderators").none? + channels = user.chat_channels + + ChatChannel.find_by(slug: "tag-moderators").add_users(user) unless channels.exists?(slug: "tag-moderators") + if tag.mod_chat_channel_id - ChatChannel.find(tag.mod_chat_channel_id).add_users(user) if user.chat_channels.where(id: tag.mod_chat_channel_id).none? + ChatChannel.find(tag.mod_chat_channel_id).add_users(user) unless channels.exists?(id: tag.mod_chat_channel_id) else channel = ChatChannel.create_with_users( users: ([user] + User.with_role(:mod_relations_admin)).flatten.uniq, diff --git a/app/labor/badge_rewarder.rb b/app/labor/badge_rewarder.rb index 302add4e3..5a5ef36ee 100644 --- a/app/labor/badge_rewarder.rb +++ b/app/labor/badge_rewarder.rb @@ -11,7 +11,8 @@ module BadgeRewarder def self.award_yearly_club_badges (1..3).each do |i| - message = "Happy #{ApplicationConfig['COMMUNITY_NAME']} birthday! Can you believe it's been #{i} #{'year'.pluralize(i)} already?!" + message = "Happy #{ApplicationConfig['COMMUNITY_NAME']} birthday! " \ + "Can you believe it's been #{i} #{'year'.pluralize(i)} already?!" badge = Badge.find_by!(slug: "#{YEARS[i]}-year-club") User.where("created_at < ? AND created_at > ?", i.year.ago, i.year.ago - 2.days).find_each do |user| achievement = BadgeAchievement.create( @@ -62,13 +63,16 @@ module BadgeRewarder award_badges( [winning_article.user.username], tag.badge.slug, - "Congratulations on posting the most beloved [##{tag.name}](#{URL.tag(tag)}) post from the past seven days! Your winning post was [#{winning_article.title}](#{URL.article(winning_article)}). (You can only win once per badge-eligible tag)", + "Congratulations on posting the most beloved [##{tag.name}](#{URL.tag(tag)}) post " \ + "from the past seven days! " \ + "Your winning post was [#{winning_article.title}](#{URL.article(winning_article)}). " \ + "(You can only win once per badge-eligible tag)", ) end end end - def self.award_contributor_badges_from_github(since = 1.day.ago, message_markdown = "Thank you so much for your contributions!") + def self.award_contributor_badges_from_github(since = 1.day.ago, msg = "Thank you so much for your contributions!") badge = Badge.find_by!(slug: "dev-contributor") REPOSITORIES.each do |repo| @@ -77,7 +81,7 @@ module BadgeRewarder authors_uids = commits.map { |commit| commit.author.id } Identity.github.where(uid: authors_uids).find_each do |i| BadgeAchievement.where(user_id: i.user_id, badge_id: badge.id).first_or_create( - rewarding_context_message_markdown: message_markdown, + rewarding_context_message_markdown: msg, ) end end @@ -85,11 +89,14 @@ module BadgeRewarder def self.award_streak_badge(num_weeks) # No credit for super low quality - article_user_ids = Article.published.where("published_at > ? AND score > ?", 1.week.ago, MINIMUM_QUALITY).pluck(:user_id) + article_user_ids = Article.published. + where("published_at > ? AND score > ?", 1.week.ago, MINIMUM_QUALITY). + pluck(:user_id) message = if num_weeks == LONGEST_STREAK_WEEKS LONGEST_STREAK_MESSAGE else - "Congrats on achieving this streak! Consistent writing is hard. The next streak badge you can get is the #{num_weeks * 2} Week Badge. 😉" + "Congrats on achieving this streak! Consistent writing is hard. " \ + "The next streak badge you can get is the #{num_weeks * 2} Week Badge. 😉" end users = User.where(id: article_user_ids).where("articles_count >= ?", num_weeks) usernames = [] @@ -97,7 +104,8 @@ module BadgeRewarder count = 0 num_weeks.times do |i| num = i + 1 - count += 1 if user.articles.published.where("published_at > ? AND published_at < ?", num.weeks.ago, (num - 1).weeks.ago).any? + count += 1 if user.articles.published.where("published_at > ? AND published_at < ?", num.weeks.ago, + (num - 1).weeks.ago).any? end usernames << user.username if count >= num_weeks end diff --git a/app/labor/bufferizer.rb b/app/labor/bufferizer.rb index 821acded1..588aa7435 100644 --- a/app/labor/bufferizer.rb +++ b/app/labor/bufferizer.rb @@ -27,13 +27,15 @@ class Bufferizer end def main_tweet! - BufferUpdate.buff!(@article.id, twitter_buffer_text, ApplicationConfig["BUFFER_TWITTER_ID"], "twitter", nil, @admin_id) + BufferUpdate.buff!(@article.id, twitter_buffer_text, ApplicationConfig["BUFFER_TWITTER_ID"], "twitter", nil, + @admin_id) @article.update(last_buffered: Time.current) end def facebook_post! BufferUpdate.buff!(@article.id, fb_buffer_text, ApplicationConfig["BUFFER_FACEBOOK_ID"], "facebook", nil, @admin_id) - BufferUpdate.buff!(@article.id, fb_buffer_text + social_tags, ApplicationConfig["BUFFER_LINKEDIN_ID"], "linkedin", nil, @admin_id) + BufferUpdate.buff!(@article.id, fb_buffer_text + social_tags, ApplicationConfig["BUFFER_LINKEDIN_ID"], "linkedin", + nil, @admin_id) @article.update(facebook_last_buffered: Time.current) end diff --git a/app/labor/error_message_cleaner.rb b/app/labor/error_message_cleaner.rb index 8e6c21d4a..3565cb6e7 100644 --- a/app/labor/error_message_cleaner.rb +++ b/app/labor/error_message_cleaner.rb @@ -6,8 +6,9 @@ class ErrorMessageCleaner end def clean - if error_message.include? "expected key while parsing a block mapping at line" - "There was a problem parsing the front-matter YAML. Perhaps you need to escape a quote or a colon or something. Email #{SiteConfig.email_addresses[:default]} if you are having trouble." + if error_message.include?("expected key while parsing a block mapping at line") + "There was a problem parsing the front-matter YAML. Perhaps you need to escape a quote " \ + "or a colon or something. Email #{SiteConfig.email_addresses[:default]} if you are having trouble." else error_message end diff --git a/app/labor/follow_checker.rb b/app/labor/follow_checker.rb index 1c880f8b8..3147488ae 100644 --- a/app/labor/follow_checker.rb +++ b/app/labor/follow_checker.rb @@ -10,7 +10,8 @@ class FollowChecker def cached_follow_check return false unless follower - Rails.cache.fetch("user-#{follower.id}-#{follower.updated_at.rfc3339}/is_following_#{followable_type}_#{followable_id}", expires_in: 20.hours) do + cache_key = "user-#{follower.id}-#{follower.updated_at.rfc3339}/is_following_#{followable_type}_#{followable_id}" + Rails.cache.fetch(cache_key, expires_in: 20.hours) do followable = if followable_type == "Tag" Tag.find(followable_id) elsif followable_type == "Organization" diff --git a/app/labor/generated_image.rb b/app/labor/generated_image.rb index e570634db..78043a571 100644 --- a/app/labor/generated_image.rb +++ b/app/labor/generated_image.rb @@ -23,7 +23,8 @@ class GeneratedImage return resource.main_image if resource.main_image.present? return resource.video_thumbnail_url if resource.video_thumbnail_url.present? - cloudinary_generated_url "/article/#{resource.id}?bust=#{resource.comments_count}-#{resource.title}-#{resource.published}" + path = "/article/#{resource.id}?bust=#{resource.comments_count}-#{resource.title}-#{resource.published}" + cloudinary_generated_url(path) end def cloudinary_generated_url(path) diff --git a/app/labor/markdown_parser.rb b/app/labor/markdown_parser.rb index 7f7caee80..bee6ebcb0 100644 --- a/app/labor/markdown_parser.rb +++ b/app/labor/markdown_parser.rb @@ -273,7 +273,9 @@ class MarkdownParser def wrap_all_images_in_links(html) doc = Nokogiri::HTML.fragment(html) doc.search("p img").each do |image| - image.swap("#{image}") unless image.parent.name == "a" + next if image.parent.name == "a" + + image.swap("#{image}") end doc.to_html end diff --git a/app/liquid_tags/codepen_tag.rb b/app/liquid_tags/codepen_tag.rb index 448493494..469043534 100644 --- a/app/liquid_tags/codepen_tag.rb +++ b/app/liquid_tags/codepen_tag.rb @@ -1,6 +1,8 @@ class CodepenTag < LiquidTagBase PARTIAL = "liquids/codepen".freeze - URL_REGEXP = /\A(http|https):\/\/(codepen\.io|codepen\.io\/team)\/[a-zA-Z0-9_\-]{1,30}\/pen\/([a-zA-Z]{5,7})\/{0,1}\z/.freeze + URL_REGEXP = + /\A(http|https):\/\/(codepen\.io|codepen\.io\/team)\/[a-zA-Z0-9_\-]{1,30}\/pen\/([a-zA-Z]{5,7})\/{0,1}\z/. + freeze def initialize(_tag_name, link, _parse_context) super diff --git a/app/liquid_tags/codesandbox_tag.rb b/app/liquid_tags/codesandbox_tag.rb index 5537f5d40..dabe5889e 100644 --- a/app/liquid_tags/codesandbox_tag.rb +++ b/app/liquid_tags/codesandbox_tag.rb @@ -1,6 +1,11 @@ class CodesandboxTag < LiquidTagBase PARTIAL = "liquids/codesandbox".freeze - OPTIONS_REGEXP = /\A(initialpath=([a-zA-Z0-9\-_\/.@%])+)\Z|\A(module=([a-zA-Z0-9\-_\/.@%])+)\Z|\A(runonclick=((0|1){1}))\Z|\Aview=(editor|split|preview)\Z/.freeze + OPTIONS_REGEXP = + /\A(initialpath=([a-zA-Z0-9\-_\/.@%])+)\Z| + \A(module=([a-zA-Z0-9\-_\/.@%])+)\Z| + \A(runonclick=((0|1){1}))\Z| + \Aview=(editor|split|preview)\Z/x. + freeze def initialize(_tag_name, id, _parse_context) super diff --git a/app/liquid_tags/gist_tag.rb b/app/liquid_tags/gist_tag.rb index 57eb9d90c..855906ae9 100644 --- a/app/liquid_tags/gist_tag.rb +++ b/app/liquid_tags/gist_tag.rb @@ -1,5 +1,8 @@ class GistTag < LiquidTagBase PARTIAL = "liquids/gist".freeze + VALID_LINK_REGEXP = + /\Ahttps:\/\/gist\.github\.com\/([a-zA-Z0-9](-?[a-zA-Z0-9]){0,38})\/([a-zA-Z0-9]){1,32}(\/[a-zA-Z0-9]+)?\Z/. + freeze def initialize(_tag_name, link, _parse_context) super @@ -46,8 +49,7 @@ class GistTag < LiquidTagBase end def valid_link?(link) - (link =~ /\Ahttps:\/\/gist\.github\.com\/([a-zA-Z0-9](-?[a-zA-Z0-9]){0,38})\/([a-zA-Z0-9]){1,32}(\/[a-zA-Z0-9]+)?\Z/)&. - zero? + (link =~ VALID_LINK_REGEXP)&.zero? end def valid_option?(option) diff --git a/app/liquid_tags/reddit_tag.rb b/app/liquid_tags/reddit_tag.rb index e06e24005..dcd4d6b01 100644 --- a/app/liquid_tags/reddit_tag.rb +++ b/app/liquid_tags/reddit_tag.rb @@ -33,7 +33,8 @@ class RedditTag < LiquidTagBase validate_url # Requests to Reddit require a custom `User-Agent` header to prevent 429 errors - json = HTTParty.get("#{@url}.json", headers: { "User-Agent" => "#{ApplicationConfig['COMMUNITY_NAME']} (#{URL.url})" }) + json = HTTParty.get("#{@url}.json", + headers: { "User-Agent" => "#{ApplicationConfig['COMMUNITY_NAME']} (#{URL.url})" }) # The JSON response is an array with two items. # The first one is the post itself, the second one are the comments diff --git a/app/liquid_tags/spotify_tag.rb b/app/liquid_tags/spotify_tag.rb index eee168f24..9888b8b36 100644 --- a/app/liquid_tags/spotify_tag.rb +++ b/app/liquid_tags/spotify_tag.rb @@ -41,7 +41,9 @@ class SpotifyTag < LiquidTagBase end def raise_error - raise StandardError, "Invalid Spotify Link - Be sure you're using the uri of a specific track, album, artist, playlist, or podcast episode." + msg = "Invalid Spotify Link - Be sure you're using the uri of a specific track, " \ + "album, artist, playlist, or podcast episode." + raise StandardError, msg end end diff --git a/app/liquid_tags/stackexchange_tag.rb b/app/liquid_tags/stackexchange_tag.rb index 5978d7db4..c3f5fab4b 100644 --- a/app/liquid_tags/stackexchange_tag.rb +++ b/app/liquid_tags/stackexchange_tag.rb @@ -63,7 +63,10 @@ class StackexchangeTag < LiquidTagBase def handle_response_error(response, input) raise StandardError, "Calling StackExchange API failed: #{response&.error_message}" if response.code != 200 - raise StandardError, "Couldn't find a post with that ID: {% #{tag_name} #{input} %}" if response["items"].length.zero? + + return unless response["items"].length.zero? + + raise StandardError, "Couldn't find a post with that ID: {% #{tag_name} #{input} %}" end def get_data(input) @@ -71,13 +74,17 @@ class StackexchangeTag < LiquidTagBase id = input.split(" ")[0] - post_response = HTTParty.get("#{API_URL}posts/#{id}?site=#{@site}&filter=#{FILTERS['post']}&key=#{ApplicationConfig['STACK_EXCHANGE_APP_KEY']}") + url = "#{API_URL}posts/#{id}?site=#{@site}&filter=#{FILTERS['post']}" \ + "&key=#{ApplicationConfig['STACK_EXCHANGE_APP_KEY']}" + post_response = HTTParty.get(url) handle_response_error(post_response, input) @post_type = post_response["items"][0]["post_type"] - final_response = HTTParty.get("#{API_URL}#{@post_type.pluralize}/#{id}?site=#{@site}&filter=#{FILTERS[@post_type]}&key=#{ApplicationConfig['STACK_EXCHANGE_APP_KEY']}") + url = "#{API_URL}#{@post_type.pluralize}/#{id}?site=#{@site}" \ + "&filter=#{FILTERS[@post_type]}&key=#{ApplicationConfig['STACK_EXCHANGE_APP_KEY']}" + final_response = HTTParty.get(url) handle_response_error(final_response, input) diff --git a/app/models/article.rb b/app/models/article.rb index 1454c24c2..942a37bb1 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -30,7 +30,12 @@ class Article < ApplicationRecord has_many :comments, as: :commentable, inverse_of: :commentable has_many :top_comments, - -> { where("comments.score > ? AND ancestry IS NULL and hidden_by_commentable_user is FALSE and deleted is FALSE", 10).order("comments.score DESC") }, + lambda { + where( + "comments.score > ? AND ancestry IS NULL and hidden_by_commentable_user is FALSE and deleted is FALSE", + 10, + ).order("comments.score DESC") + }, as: :commentable, inverse_of: :commentable, class_name: "Comment" @@ -78,7 +83,9 @@ class Article < ApplicationRecord after_save :bust_cache, :detect_human_language after_save :notify_slack_channel_about_publication - after_update_commit :update_notifications, if: proc { |article| article.notifications.any? && !article.saved_changes.empty? } + after_update_commit :update_notifications, if: proc { |article| + article.notifications.any? && !article.saved_changes.empty? + } after_commit :async_score_calc, :update_main_image_background_hex, :touch_collection, on: %i[create update] after_commit :index_to_elasticsearch, on: %i[create update] after_commit :sync_related_elasticsearch_docs, on: %i[create update] @@ -167,9 +174,19 @@ class Article < ApplicationRecord order(column => dir.to_sym) } - scope :feed, -> { published.includes(:taggings).select(:id, :published_at, :processed_html, :user_id, :organization_id, :title, :path, :cached_tag_list) } + scope :feed, lambda { + published.includes(:taggings). + select( + :id, :published_at, :processed_html, :user_id, :organization_id, :title, :path, :cached_tag_list + ) + } - scope :with_video, -> { published.where.not(video: [nil, ""]).where.not(video_thumbnail_url: [nil, ""]).where("score > ?", -4) } + scope :with_video, lambda { + published. + where.not(video: [nil, ""]). + where.not(video_thumbnail_url: [nil, ""]). + where("score > ?", -4) + } scope :eager_load_serialized_data, -> { includes(:user, :organization, :tags) } @@ -195,8 +212,11 @@ class Article < ApplicationRecord end def self.seo_boostable(tag = nil, time_ago = 18.days.ago) - time_ago = 5.days.ago if time_ago == "latest" # Time ago sometimes returns this phrase instead of a date - time_ago = 75.days.ago if time_ago.nil? # Time ago sometimes is given as nil and should then be the default. I know, sloppy. + # Time ago sometimes returns this phrase instead of a date + time_ago = 5.days.ago if time_ago == "latest" + + # Time ago sometimes is given as nil and should then be the default. I know, sloppy. + time_ago = 75.days.ago if time_ago.nil? relation = Article.published. order(organic_page_views_past_month_count: :desc). @@ -353,7 +373,9 @@ class Article < ApplicationRecord private def search_score - calculated_score = hotness_score.to_i + ((comments_count * 3).to_i + public_reactions_count.to_i * 300 * user.reputation_modifier * score.to_i) + comments_score = (comments_count * 3).to_i + partial_score = (comments_score + public_reactions_count.to_i * 300 * user.reputation_modifier * score.to_i) + calculated_score = hotness_score.to_i + partial_score calculated_score.to_i end @@ -457,7 +479,10 @@ class Article < ApplicationRecord self.published_at = parse_date(front_matter["date"]) if published self.main_image = determine_image(front_matter) self.canonical_url = front_matter["canonical_url"] if front_matter["canonical_url"].present? - self.description = front_matter["description"] if front_matter["description"].present? || front_matter["title"].present? # Do this if frontmatte exists at all + + update_description = front_matter["description"].present? || front_matter["title"].present? + self.description = front_matter["description"] if update_description + self.collection_id = nil if front_matter["title"].present? self.collection_id = Collection.find_series(front_matter["series"], user).id if front_matter["series"].present? end @@ -497,7 +522,8 @@ class Article < ApplicationRecord end def remove_tag_adjustments_from_tag_list - tags_to_remove = TagAdjustment.where(article_id: id, adjustment_type: "removal", status: "committed").pluck(:tag_name) + tags_to_remove = TagAdjustment.where(article_id: id, adjustment_type: "removal", + status: "committed").pluck(:tag_name) tag_list.remove(tags_to_remove, parse: true) if tags_to_remove.present? end @@ -510,12 +536,20 @@ class Article < ApplicationRecord end def validate_video - return errors.add(:published, "cannot be set to true if video is still processing") if published && video_state == "PROGRESSING" - return errors.add(:video, "cannot be added by member without permission") if video.present? && user.created_at > 2.weeks.ago + if published && video_state == "PROGRESSING" + return errors.add(:published, + "cannot be set to true if video is still processing") + end + + return unless video.present? && user.created_at > 2.weeks.ago + + errors.add(:video, "cannot be added by member without permission") end def validate_collection_permission - errors.add(:collection_id, "must be one you have permission to post to") if collection && collection.user_id != user_id + return unless collection && collection.user_id != user_id + + errors.add(:collection_id, "must be one you have permission to post to") end def past_or_present_date @@ -525,7 +559,9 @@ class Article < ApplicationRecord end def canonical_url_must_not_have_spaces - errors.add(:canonical_url, "must not have spaces") if canonical_url.to_s.match?(/[[:space:]]/) + return unless canonical_url.to_s.match?(/[[:space:]]/) + + errors.add(:canonical_url, "must not have spaces") end def create_slug @@ -596,9 +632,12 @@ class Article < ApplicationRecord end def set_nth_published_at - published_article_ids = user.articles.published.order("published_at ASC").pluck(:id) + return unless nth_published_by_author.zero? && published + + published_article_ids = user.articles.published.order(published_at: :asc).pluck(:id) index = published_article_ids.index(id) - self.nth_published_by_author = (index || published_article_ids.size) + 1 if nth_published_by_author.zero? && published + + self.nth_published_by_author = (index || published_article_ids.size) + 1 end def title_to_slug diff --git a/app/models/backup_data.rb b/app/models/backup_data.rb index 3665bbf5a..b8242fe62 100644 --- a/app/models/backup_data.rb +++ b/app/models/backup_data.rb @@ -4,7 +4,8 @@ class BackupData < ApplicationRecord validates :instance_id, :instance_type, :json_data, presence: true def self.backup!(instance) - BackupData.create!(instance_type: instance.class.name, instance_id: instance.id, instance_user_id: instance.user_id, json_data: instance.attributes) + BackupData.create!(instance_type: instance.class.name, instance_id: instance.id, + instance_user_id: instance.user_id, json_data: instance.attributes) end def recover! diff --git a/app/models/buffer_update.rb b/app/models/buffer_update.rb index ee37815f7..ceb7bedc5 100644 --- a/app/models/buffer_update.rb +++ b/app/models/buffer_update.rb @@ -5,7 +5,9 @@ class BufferUpdate < ApplicationRecord validate :validate_body_text_recent_uniqueness, :validate_suggestion_limit validates :status, inclusion: { in: %w[pending sent_direct confirmed dismissed] } - def self.buff!(article_id, text, buffer_profile_id_code, social_service_name = "twitter", tag_id = nil, admin_id = nil) + def self.buff!( + article_id, text, buffer_profile_id_code, social_service_name = "twitter", tag_id = nil, admin_id = nil + ) buffer_response = send_to_buffer(text, buffer_profile_id_code) create( article_id: article_id, @@ -23,7 +25,8 @@ class BufferUpdate < ApplicationRecord buffer_update = BufferUpdate.find(buffer_update_id) if status == "confirmed" buffer_response = send_to_buffer(body_text, buffer_update.buffer_profile_id_code) - buffer_update.update!(buffer_response: buffer_response, status: status, approver_user_id: admin_id, body_text: body_text) + buffer_update.update!(buffer_response: buffer_response, status: status, approver_user_id: admin_id, + body_text: body_text) else buffer_update.update!(status: status, approver_user_id: admin_id) end @@ -56,14 +59,18 @@ class BufferUpdate < ApplicationRecord def validate_body_text_recent_uniqueness return if persisted? - if BufferUpdate.where(body_text: body_text, article_id: article_id, tag_id: tag_id, social_service_name: social_service_name). - where("created_at > ?", 2.minutes.ago).any? - errors.add(:body_text, "\"#{body_text}\" has already been submitted very recently") - end + relation = BufferUpdate. + where(body_text: body_text, article_id: article_id, tag_id: tag_id, social_service_name: social_service_name). + where("created_at > ?", 2.minutes.ago) + + return unless relation.any? + + errors.add(:body_text, "\"#{body_text}\" has already been submitted very recently") end def validate_suggestion_limit - return unless BufferUpdate.where(article_id: article_id, tag_id: tag_id, social_service_name: social_service_name).count > 2 + return unless BufferUpdate.where(article_id: article_id, tag_id: tag_id, + social_service_name: social_service_name).count > 2 errors.add(:article_id, "already has multiple suggestions for #{social_service_name}") end diff --git a/app/models/chat_channel.rb b/app/models/chat_channel.rb index 25feb30fa..b24dcc811 100644 --- a/app/models/chat_channel.rb +++ b/app/models/chat_channel.rb @@ -10,11 +10,19 @@ class ChatChannel < ApplicationRecord has_many :chat_channel_memberships, dependent: :destroy has_many :users, through: :chat_channel_memberships - has_many :active_memberships, -> { where status: "active" }, class_name: "ChatChannelMembership", inverse_of: :chat_channel - has_many :pending_memberships, -> { where status: "pending" }, class_name: "ChatChannelMembership", inverse_of: :chat_channel - has_many :rejected_memberships, -> { where status: "rejected" }, class_name: "ChatChannelMembership", inverse_of: :chat_channel + has_many :active_memberships, lambda { + where status: "active" + }, class_name: "ChatChannelMembership", inverse_of: :chat_channel + has_many :pending_memberships, lambda { + where status: "pending" + }, class_name: "ChatChannelMembership", inverse_of: :chat_channel + has_many :rejected_memberships, lambda { + where status: "rejected" + }, class_name: "ChatChannelMembership", inverse_of: :chat_channel has_many :mod_memberships, -> { where role: "mod" }, class_name: "ChatChannelMembership", inverse_of: :chat_channel - has_many :requested_memberships, -> { where status: "joining_request" }, class_name: "ChatChannelMembership", inverse_of: :chat_channel + has_many :requested_memberships, lambda { + where status: "joining_request" + }, class_name: "ChatChannelMembership", inverse_of: :chat_channel has_many :active_users, through: :active_memberships, class_name: "User", source: :user has_many :pending_users, through: :pending_memberships, class_name: "User", source: :user has_many :rejected_users, through: :rejected_memberships, class_name: "User", source: :user @@ -67,7 +75,12 @@ class ChatChannel < ApplicationRecord raise "Invalid direct channel" if invalid_direct_channel?(users, channel_type) usernames = users.map(&:username).sort - slug = channel_type == "direct" ? usernames.join("/") : contrived_name.to_s.parameterize + "-" + rand(100_000).to_s(26) + slug = if channel_type == "direct" + usernames.join("/") + else + "#{contrived_name.to_s.parameterize}-#{rand(100_000).to_s(26)}" + end + contrived_name = "Direct chat between " + usernames.join(" and ") if channel_type == "direct" channel = find_or_create_chat_channel(channel_type, slug, contrived_name) if channel_type == "direct" @@ -125,7 +138,8 @@ class ChatChannel < ApplicationRecord invitation_sent += 1 end else - membership = ChatChannelMembership.create(user_id: user.id, chat_channel_id: id, role: membership_role, status: "pending") + membership = ChatChannelMembership.create(user_id: user.id, chat_channel_id: id, role: membership_role, + status: "pending") if membership.persisted? NotifyMailer.with(membership: membership, inviter: inviter).channel_invite_email.deliver_later invitation_sent += 1 diff --git a/app/models/comment.rb b/app/models/comment.rb index 1b12860a1..9f9c937f7 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -165,7 +165,9 @@ class Comment < ApplicationRecord def wrap_timestamps_if_video_present! return unless commentable_type != "PodcastEpisode" && commentable.video.present? - self.processed_html = processed_html.gsub(/(([0-9]:)?)(([0-5][0-9]|[0-9])?):[0-5][0-9]/) { |string| "#{string}" } + self.processed_html = processed_html.gsub(/(([0-9]:)?)(([0-5][0-9]|[0-9])?):[0-5][0-9]/) do |string| + "#{string}" + end end def shorten_urls! diff --git a/app/models/email_authorization.rb b/app/models/email_authorization.rb index 52648c081..2b99337e0 100644 --- a/app/models/email_authorization.rb +++ b/app/models/email_authorization.rb @@ -2,8 +2,9 @@ class EmailAuthorization < ApplicationRecord before_create :generate_confirmation_token belongs_to :user + # uuid_issue is a specific case where a user deletes their old auth account and recreates it, + # leaving us with the incorrect uuid TYPES = %w[merge_request account_lockout uuid_issue account_ownership].freeze - # uuid_issue is a specific case where a user deletes their old auth account and recreates it, leaving us with the incorrect uuid validates :type_of, presence: true validates :type_of, inclusion: { in: TYPES } diff --git a/app/models/html_variant.rb b/app/models/html_variant.rb index 6a26bc0be..de8e2b0a6 100644 --- a/app/models/html_variant.rb +++ b/app/models/html_variant.rb @@ -18,7 +18,8 @@ class HtmlVariant < ApplicationRecord scope :relevant, -> { where(approved: true, published: true) } def calculate_success_rate! - self.success_rate = html_variant_successes.size.to_f / (html_variant_trials.size * 10.0) # x10 because we only capture every 10th + # x10 because we only capture every 10th + self.success_rate = html_variant_successes.size.to_f / (html_variant_trials.size * 10.0) save! end diff --git a/app/models/identity.rb b/app/models/identity.rb index b3517f438..72a982160 100644 --- a/app/models/identity.rb +++ b/app/models/identity.rb @@ -10,9 +10,13 @@ class Identity < ApplicationRecord validates :provider, inclusion: { in: Authentication::Providers.available.map(&:to_s) } validates :uid, :provider, presence: true - validates :uid, uniqueness: { scope: :provider }, if: proc { |identity| identity.uid_changed? || identity.provider_changed? } + validates :uid, uniqueness: { scope: :provider }, if: proc { |identity| + identity.uid_changed? || identity.provider_changed? + } validates :user_id, presence: true - validates :user_id, uniqueness: { scope: :provider }, if: proc { |identity| identity.user_id_changed? || identity.provider_changed? } + validates :user_id, uniqueness: { scope: :provider }, if: proc { |identity| + identity.user_id_changed? || identity.provider_changed? + } # TODO: [thepracticaldev/oss] should this be transitioned to JSON? serialize :auth_data_dump diff --git a/app/models/languages.rb b/app/models/languages.rb index 4a9a9d594..3bae43b38 100644 --- a/app/models/languages.rb +++ b/app/models/languages.rb @@ -1,5 +1,6 @@ module Languages - LIST = { "en" => "English", "ja" => "Japanese", "es" => "Spanish", "fr" => "French", "it" => "Italian", "pt" => "Portuguese" }.freeze + LIST = { "en" => "English", "ja" => "Japanese", "es" => "Spanish", "fr" => "French", "it" => "Italian", + "pt" => "Portuguese" }.freeze module_function diff --git a/app/models/listing.rb b/app/models/listing.rb index 078ab4ae7..9dd03d514 100644 --- a/app/models/listing.rb +++ b/app/models/listing.rb @@ -81,7 +81,10 @@ class Listing < ApplicationRecord def restrict_markdown_input markdown_string = body_markdown.to_s - errors.add(:body_markdown, "has too many linebreaks. No more than 12 allowed.") if markdown_string.scan(/(?=\n)/).count > 12 + if markdown_string.scan(/(?=\n)/).count > 12 + errors.add(:body_markdown, + "has too many linebreaks. No more than 12 allowed.") + end errors.add(:body_markdown, "is not allowed to include images.") if markdown_string.include?("![") errors.add(:body_markdown, "is not allowed to include liquid tags.") if markdown_string.include?("{% ") end diff --git a/app/models/message.rb b/app/models/message.rb index 7b9adf247..87d756654 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -98,6 +98,7 @@ class Message < ApplicationRecord html end + # rubocop:disable Layout/LineLength def append_rich_links(html) doc = Nokogiri::HTML(html) doc.css("a").each do |anchor| @@ -143,6 +144,7 @@ class Message < ApplicationRecord end html end + # rubocop:enable Layout/LineLength def handle_slash_command(html) response = if html.to_s.strip == "

/call

" @@ -195,15 +197,21 @@ class Message < ApplicationRecord end def rich_link_article(link) - Article.find_by(slug: link["href"].split("/")[4].split("?")[0]) if link["href"].include?("//#{ApplicationConfig['APP_DOMAIN']}/") && link["href"].split("/")[4] + return unless link["href"].include?("//#{ApplicationConfig['APP_DOMAIN']}/") && link["href"].split("/")[4] + + Article.find_by(slug: link["href"].split("/")[4].split("?")[0]) end def rich_link_tag(link) - Tag.find_by(name: link["href"].split("/t/")[1].split("/")[0]) if link["href"].include?("//#{ApplicationConfig['APP_DOMAIN']}/t/") + return unless link["href"].include?("//#{ApplicationConfig['APP_DOMAIN']}/t/") + + Tag.find_by(name: link["href"].split("/t/")[1].split("/")[0]) end def rich_user_link(link) - User.find_by(username: link["href"].split("/")[3].split("/")[0]) if link["href"].include?("//#{ApplicationConfig['APP_DOMAIN']}/") + return unless link["href"].include?("//#{ApplicationConfig['APP_DOMAIN']}/") + + User.find_by(username: link["href"].split("/")[3].split("/")[0]) end def send_email_if_appropriate diff --git a/app/models/page.rb b/app/models/page.rb index 5e63e726e..0f01173d5 100644 --- a/app/models/page.rb +++ b/app/models/page.rb @@ -39,12 +39,21 @@ class Page < ApplicationRecord end def body_present - errors.add(:body_markdown, "must exist if body_html or body_json doesn't exist.") if body_markdown.blank? && body_html.blank? && body_json.blank? + return unless body_markdown.blank? && body_html.blank? && body_json.blank? + + errors.add(:body_markdown, "must exist if body_html or body_json doesn't exist.") end def unique_slug_including_users_and_orgs - slug_exists = User.exists?(username: slug) || Organization.exists?(slug: slug) || Podcast.exists?(slug: slug) || slug.include?("sitemap-") - errors.add(:slug, "is taken.") if slug_exists + slug_exists = ( + User.exists?(username: slug) || + Organization.exists?(slug: slug) || + Podcast.exists?(slug: slug) || + slug.include?("sitemap-") + ) + return unless slug_exists + + errors.add(:slug, "is taken.") end def bust_cache diff --git a/app/models/path_redirect.rb b/app/models/path_redirect.rb index 89f125d26..8a4d49276 100644 --- a/app/models/path_redirect.rb +++ b/app/models/path_redirect.rb @@ -5,7 +5,9 @@ class PathRedirect < ApplicationRecord validates :new_path, presence: true # Validate old_path != new_path - validates :old_path, exclusion: { in: ->(path_redirect) { [path_redirect.new_path] }, message: "the old_path cannot be the same as the new_path" } + validates :old_path, exclusion: { in: lambda { |path_redirect| + [path_redirect.new_path] + }, message: "the old_path cannot be the same as the new_path" } validates :source, inclusion: { in: SOURCES }, allow_blank: true diff --git a/app/models/poll_vote.rb b/app/models/poll_vote.rb index dcc5b4e13..11a89a126 100644 --- a/app/models/poll_vote.rb +++ b/app/models/poll_vote.rb @@ -6,7 +6,9 @@ class PollVote < ApplicationRecord counter_culture :poll_option counter_culture :poll - validates :poll_id, presence: true, uniqueness: { scope: :user_id } # In the future we'll remove this constraint if/when we allow multi-answer polls + # In the future we'll remove this constraint if/when we allow multi-answer polls + validates :poll_id, presence: true, uniqueness: { scope: :user_id } + validates :poll_option_id, presence: true, uniqueness: { scope: :user_id } validate :one_vote_per_poll_per_user diff --git a/app/models/rating_vote.rb b/app/models/rating_vote.rb index 70c162cb6..fad020065 100644 --- a/app/models/rating_vote.rb +++ b/app/models/rating_vote.rb @@ -20,6 +20,8 @@ class RatingVote < ApplicationRecord private def permissions - errors.add(:user_id, "is not permitted to take this action.") if context == "explicit" && !user&.trusted && user_id != article&.user_id + return unless context == "explicit" && !user&.trusted && user_id != article&.user_id + + errors.add(:user_id, "is not permitted to take this action.") end end diff --git a/app/models/reaction.rb b/app/models/reaction.rb index bab1a92d9..b25b5ff37 100644 --- a/app/models/reaction.rb +++ b/app/models/reaction.rb @@ -54,7 +54,8 @@ class Reaction < ApplicationRecord def cached_any_reactions_for?(reactable, user, category) class_name = reactable.class.name == "ArticleDecorator" ? "Article" : reactable.class.name - cache_name = "any_reactions_for-#{class_name}-#{reactable.id}-#{user.reactions_count}-#{user.public_reactions_count}-#{category}" + cache_name = "any_reactions_for-#{class_name}-#{reactable.id}-" \ + "#{user.reactions_count}-#{user.public_reactions_count}-#{category}" Rails.cache.fetch(cache_name, expires_in: 24.hours) do Reaction.where(reactable_id: reactable.id, reactable_type: class_name, user: user, category: category).any? end diff --git a/app/models/site_config.rb b/app/models/site_config.rb index fc3cc76e8..bdd744e19 100644 --- a/app/models/site_config.rb +++ b/app/models/site_config.rb @@ -124,7 +124,8 @@ class SiteConfig < RailsSettings::Base # User Experience # These are the default UX settings, which can be overridded by individual user preferences. - field :feed_style, type: :string, default: "basic" # basic (current default), rich (cover image on all posts), compact (more minimal) + # basic (current default), rich (cover image on all posts), compact (more minimal) + field :feed_style, type: :string, default: "basic" # Broadcast field :welcome_notifications_live_at, type: :date diff --git a/app/models/tag_adjustment.rb b/app/models/tag_adjustment.rb index be2f8311c..75fa9a084 100644 --- a/app/models/tag_adjustment.rb +++ b/app/models/tag_adjustment.rb @@ -29,7 +29,12 @@ class TagAdjustment < ApplicationRecord end def article_tag_list - errors.add(:tag_id, "selected for removal is not a current live tag.") if adjustment_type == "removal" && article.tag_list.none? { |tag| tag.casecmp(tag_name).zero? } + if adjustment_type == "removal" && article.tag_list.none? do |tag| + tag.casecmp(tag_name).zero? + end + errors.add(:tag_id, + "selected for removal is not a current live tag.") + end errors.add(:base, "4 tags max per article.") if adjustment_type == "addition" && article.tag_list.count > 3 end end diff --git a/app/models/user.rb b/app/models/user.rb index 1c5de99b8..0dd42ccec 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -13,11 +13,15 @@ class User < ApplicationRecord FONTS = %w[default sans_serif monospace comic_sans open_dyslexic].freeze GITLAB_URL_REGEXP = /\A(http(s)?:\/\/)?(www.gitlab.com|gitlab.com)\/.*\z/.freeze INBOXES = %w[open private].freeze - INSTAGRAM_URL_REGEXP = /\A(http(s)?:\/\/)?(?:www.)?instagram.com\/(?=.{1,30}\/?$)([a-zA-Z\d_]\.?)*[a-zA-Z\d_]+\/?\z/.freeze + INSTAGRAM_URL_REGEXP = + /\A(http(s)?:\/\/)?(?:www.)?instagram.com\/(?=.{1,30}\/?$)([a-zA-Z\d_]\.?)*[a-zA-Z\d_]+\/?\z/.freeze + LINKEDIN_URL_REGEXP = /\A(http(s)?:\/\/)?(www.linkedin.com|linkedin.com|[A-Za-z]{2}.linkedin.com)\/.*\z/.freeze MEDIUM_URL_REGEXP = /\A(http(s)?:\/\/)?(www.medium.com|medium.com)\/.*\z/.freeze NAVBARS = %w[default static].freeze - STACKOVERFLOW_URL_REGEXP = /\A(http(s)?:\/\/)?(((www|pt|ru|es|ja).)?stackoverflow.com|(www.)?stackexchange.com)\/.*\z/.freeze + STACKOVERFLOW_URL_REGEXP = + /\A(http(s)?:\/\/)?(((www|pt|ru|es|ja).)?stackoverflow.com|(www.)?stackexchange.com)\/.*\z/.freeze + YOUTUBE_URL_REGEXP = /\A(http(s)?:\/\/)?(www.youtube.com|youtube.com)\/.*\z/.freeze STREAMING_PLATFORMS = %w[twitch].freeze THEMES = %w[default night_theme pink_theme minimal_light_theme ten_x_hacker_theme].freeze @@ -45,22 +49,30 @@ class User < ApplicationRecord acts_as_followable acts_as_follower - has_many :source_authored_user_subscriptions, class_name: "UserSubscription", foreign_key: :author_id, inverse_of: :author, dependent: :destroy + has_many :source_authored_user_subscriptions, class_name: "UserSubscription", + foreign_key: :author_id, inverse_of: :author, dependent: :destroy has_many :subscribers, through: :source_authored_user_subscriptions, dependent: :destroy - has_many :subscribed_to_user_subscriptions, class_name: "UserSubscription", foreign_key: :subscriber_id, inverse_of: :subscriber, dependent: :destroy + has_many :subscribed_to_user_subscriptions, class_name: "UserSubscription", + foreign_key: :subscriber_id, inverse_of: :subscriber, dependent: :destroy - has_many :access_grants, class_name: "Doorkeeper::AccessGrant", foreign_key: :resource_owner_id, inverse_of: :resource_owner, dependent: :delete_all - has_many :access_tokens, class_name: "Doorkeeper::AccessToken", foreign_key: :resource_owner_id, inverse_of: :resource_owner, dependent: :delete_all - has_many :affected_feedback_messages, class_name: "FeedbackMessage", inverse_of: :affected, foreign_key: :affected_id, dependent: :nullify + has_many :access_grants, class_name: "Doorkeeper::AccessGrant", + foreign_key: :resource_owner_id, inverse_of: :resource_owner, dependent: :delete_all + has_many :access_tokens, class_name: "Doorkeeper::AccessToken", + foreign_key: :resource_owner_id, inverse_of: :resource_owner, dependent: :delete_all + has_many :affected_feedback_messages, class_name: "FeedbackMessage", + inverse_of: :affected, foreign_key: :affected_id, dependent: :nullify has_many :api_secrets, dependent: :destroy has_many :articles, dependent: :destroy has_many :audit_logs, dependent: :nullify has_many :authored_notes, inverse_of: :author, class_name: "Note", foreign_key: :author_id, dependent: :delete_all - has_many :backup_data, foreign_key: "instance_user_id", inverse_of: :instance_user, class_name: "BackupData", dependent: :delete_all + has_many :backup_data, foreign_key: "instance_user_id", + inverse_of: :instance_user, class_name: "BackupData", dependent: :delete_all has_many :badge_achievements, dependent: :destroy has_many :badges, through: :badge_achievements - has_many :blocked_blocks, class_name: "UserBlock", foreign_key: :blocked_id, inverse_of: :blocked, dependent: :delete_all - has_many :blocker_blocks, class_name: "UserBlock", foreign_key: :blocker_id, inverse_of: :blocker, dependent: :delete_all + has_many :blocked_blocks, class_name: "UserBlock", + foreign_key: :blocked_id, inverse_of: :blocked, dependent: :delete_all + has_many :blocker_blocks, class_name: "UserBlock", + foreign_key: :blocker_id, inverse_of: :blocker, dependent: :delete_all has_many :chat_channel_memberships, dependent: :destroy has_many :chat_channels, through: :chat_channel_memberships has_many :listings, dependent: :destroy @@ -82,7 +94,8 @@ class User < ApplicationRecord has_many :notification_subscriptions, dependent: :destroy has_many :user_optional_fields, dependent: :destroy has_many :notifications, dependent: :destroy - has_many :offender_feedback_messages, class_name: "FeedbackMessage", inverse_of: :offender, foreign_key: :offender_id, dependent: :nullify + has_many :offender_feedback_messages, class_name: "FeedbackMessage", + inverse_of: :offender, foreign_key: :offender_id, dependent: :nullify has_many :organization_memberships, dependent: :destroy has_many :organizations, through: :organization_memberships has_many :page_views, dependent: :destroy @@ -91,7 +104,8 @@ class User < ApplicationRecord has_many :profile_pins, as: :profile, inverse_of: :profile, dependent: :delete_all has_many :rating_votes, dependent: :destroy has_many :reactions, dependent: :destroy - has_many :reporter_feedback_messages, class_name: "FeedbackMessage", inverse_of: :reporter, foreign_key: :reporter_id, dependent: :nullify + has_many :reporter_feedback_messages, class_name: "FeedbackMessage", + inverse_of: :reporter, foreign_key: :reporter_id, dependent: :nullify has_many :response_templates, inverse_of: :user, dependent: :destroy has_many :tweets, dependent: :destroy has_many :webhook_endpoints, class_name: "Webhook::Endpoint", inverse_of: :user, dependent: :delete_all @@ -236,7 +250,8 @@ class User < ApplicationRecord else languages = [] language_settings.each_key do |setting| - languages << setting.split("prefer_language_")[1] if language_settings[setting] && setting.include?("prefer_language_") + to_split = language_settings[setting] && setting.include?("prefer_language_") + languages << setting.split("prefer_language_")[1] if to_split end @preferred_languages_array = languages end diff --git a/app/models/user_subscription.rb b/app/models/user_subscription.rb index 2a4c76c8c..9d306d250 100644 --- a/app/models/user_subscription.rb +++ b/app/models/user_subscription.rb @@ -13,7 +13,8 @@ class UserSubscription < ApplicationRecord validates :author_id, presence: true validates :subscriber_email, presence: true - validates :subscriber_id, presence: true, uniqueness: { scope: %i[subscriber_email user_subscription_sourceable_type user_subscription_sourceable_id] } + validates :subscriber_id, presence: true, uniqueness: { scope: %i[subscriber_email user_subscription_sourceable_type + user_subscription_sourceable_id] } validates :user_subscription_sourceable_id, presence: true validates :user_subscription_sourceable_type, presence: true, inclusion: { in: ALLOWED_TYPES } diff --git a/app/policies/liquid_tag_policy.rb b/app/policies/liquid_tag_policy.rb index 812bbfd19..ee831d2ed 100644 --- a/app/policies/liquid_tag_policy.rb +++ b/app/policies/liquid_tag_policy.rb @@ -12,14 +12,14 @@ class LiquidTagPolicy return true unless record.class.const_defined?("VALID_ROLES") raise Pundit::NotAuthorizedError, "No user found" unless user # Manually raise error to use a custom error message - raise Pundit::NotAuthorizedError, "User is not permitted to use this liquid tag" unless user_permitted_to_use_liquid_tag? + raise Pundit::NotAuthorizedError, "User is not permitted to use this liquid tag" unless user_allowed_to_use_tag? true end private - def user_permitted_to_use_liquid_tag? + def user_allowed_to_use_tag? record.class::VALID_ROLES.any? { |valid_role| user_has_valid_role?(valid_role) } end diff --git a/app/sanitizers/rendered_markdown_scrubber.rb b/app/sanitizers/rendered_markdown_scrubber.rb index 72d217d34..0f1173ee6 100644 --- a/app/sanitizers/rendered_markdown_scrubber.rb +++ b/app/sanitizers/rendered_markdown_scrubber.rb @@ -1,8 +1,17 @@ class RenderedMarkdownScrubber < Rails::Html::PermitScrubber def initialize super - self.tags = %w[a abbr add aside b blockquote br button center cite code col colgroup dd del dl dt em em figcaption h1 h2 h3 h4 h5 h6 hr i img kbd li mark ol p pre q rp rt ruby small source span strong sub sup table tbody td tfoot th thead time tr u ul video] - self.attributes = %w[alt class colspan data-conversation data-lang data-no-instant data-url em height href id loop name ref rel rowspan size span src start strong title type value width] + + self.tags = %w[ + a abbr add aside b blockquote br button center cite code col colgroup dd del dl dt em em figcaption + h1 h2 h3 h4 h5 h6 hr i img kbd li mark ol p pre q rp rt ruby small source span strong sub sup table + tbody td tfoot th thead time tr u ul video + ] + + self.attributes = %w[ + alt class colspan data-conversation data-lang data-no-instant data-url em height href id loop + name ref rel rowspan size span src start strong title type value width + ] end def allowed_node?(node) diff --git a/app/services/articles/builder.rb b/app/services/articles/builder.rb index 9bdf89518..9fa6b4e25 100644 --- a/app/services/articles/builder.rb +++ b/app/services/articles/builder.rb @@ -90,8 +90,11 @@ module Articles end def user_editor_v1 + body = "---\ntitle: \npublished: false\ndescription: " \ + "\ntags: \n//cover_image: https://direct_url_to_image.jpg\n---\n\n" + Article.new( - body_markdown: "---\ntitle: \npublished: false\ndescription: \ntags: \n//cover_image: https://direct_url_to_image.jpg\n---\n\n", + body_markdown: body, processed_html: "", user_id: @user&.id, ) diff --git a/app/services/articles/creator.rb b/app/services/articles/creator.rb index eaebefcb3..64efadcde 100644 --- a/app/services/articles/creator.rb +++ b/app/services/articles/creator.rb @@ -16,7 +16,8 @@ module Articles article = save_article if article.persisted? - NotificationSubscription.create(user: user, notifiable_id: article.id, notifiable_type: "Article", config: "all_comments") + NotificationSubscription.create(user: user, notifiable_id: article.id, notifiable_type: "Article", + config: "all_comments") Notification.send_to_followers(article, "Published") if article.published? dispatch_event(article) diff --git a/app/services/articles/destroyer.rb b/app/services/articles/destroyer.rb index 610b90fd2..89bc9a787 100644 --- a/app/services/articles/destroyer.rb +++ b/app/services/articles/destroyer.rb @@ -5,7 +5,10 @@ module Articles def call(article, event_dispatcher = Webhook::DispatchEvent) article.destroy! Notification.remove_all_without_delay(notifiable_ids: article.id, notifiable_type: "Article") - Notification.remove_all(notifiable_ids: article.comments.pluck(:id), notifiable_type: "Comment") if article.comments.exists? + if article.comments.exists? + Notification.remove_all(notifiable_ids: article.comments.pluck(:id), + notifiable_type: "Comment") + end event_dispatcher.call("article_destroyed", article) if article.published? end end diff --git a/app/services/articles/feed.rb b/app/services/articles/feed.rb index 610503073..03d39ad86 100644 --- a/app/services/articles/feed.rb +++ b/app/services/articles/feed.rb @@ -27,7 +27,9 @@ module Articles end def published_articles_by_tag - articles = Article.published.limited_column_select.includes(top_comments: :user).page(@page).per(@number_of_articles) + articles = Article.published.limited_column_select. + includes(top_comments: :user). + page(@page).per(@number_of_articles) articles = articles.cached_tagged_with(@tag) if @tag.present? # More efficient than tagged_with articles end @@ -240,7 +242,9 @@ module Articles featured_story = hot_stories.where.not(main_image: nil).first if user_signed_in hot_story_count = hot_stories.count - offset = RANDOM_OFFSET_VALUES.select { |i| i < hot_story_count }.sample # random offset, weighted more towards zero + offset = RANDOM_OFFSET_VALUES.select do |i| + i < hot_story_count + end.sample # random offset, weighted more towards zero hot_stories = hot_stories.offset(offset) new_stories = Article.published. where("score > ?", -15). diff --git a/app/services/articles/updater.rb b/app/services/articles/updater.rb index 8eb2bc049..a4376e819 100644 --- a/app/services/articles/updater.rb +++ b/app/services/articles/updater.rb @@ -44,8 +44,12 @@ module Articles # remove related notifications if unpublished if article.saved_changes["published"] == [true, false] - Notification.remove_all_by_action_without_delay(notifiable_ids: article.id, notifiable_type: "Article", action: "Published") - Notification.remove_all(notifiable_ids: article.comments.pluck(:id), notifiable_type: "Comment") if article.comments.exists? + Notification.remove_all_by_action_without_delay(notifiable_ids: article.id, notifiable_type: "Article", + action: "Published") + if article.comments.exists? + Notification.remove_all(notifiable_ids: article.comments.pluck(:id), + notifiable_type: "Comment") + end end # don't send only if article keeps being unpublished dispatch_event(article) if article.published || was_published diff --git a/app/services/broadcasts/welcome_notification/generator.rb b/app/services/broadcasts/welcome_notification/generator.rb index ba582a31c..cbf064dc1 100644 --- a/app/services/broadcasts/welcome_notification/generator.rb +++ b/app/services/broadcasts/welcome_notification/generator.rb @@ -28,7 +28,10 @@ module Broadcasts attr_reader :user, :notification_enqueued def send_welcome_notification - return if user.created_at > 3.hours.ago || received_notification?(welcome_broadcast) || commented_on_welcome_thread? + return if + user.created_at > 3.hours.ago || + received_notification?(welcome_broadcast) || + commented_on_welcome_thread? Notification.send_welcome_notification(user.id, welcome_broadcast.id) # Setting @notification_enqueued here prevents us from sending a user two welcome notifications in one day. @@ -36,14 +39,20 @@ module Broadcasts end def send_authentication_notification - return if user.created_at > 1.day.ago || authenticated_with_all_providers? || received_notification?(authentication_broadcast) + return if + user.created_at > 1.day.ago || + authenticated_with_all_providers? || + received_notification?(authentication_broadcast) Notification.send_welcome_notification(user.id, authentication_broadcast.id) @notification_enqueued = true end def send_feed_customization_notification - return if user.created_at > 3.days.ago || user_is_following_tags? || received_notification?(customize_feed_broadcast) + return if + user.created_at > 3.days.ago || + user_is_following_tags? || + received_notification?(customize_feed_broadcast) Notification.send_welcome_notification(user.id, customize_feed_broadcast.id) @notification_enqueued = true @@ -57,7 +66,10 @@ module Broadcasts end def send_discuss_and_ask_notification - return if user.created_at > 6.days.ago || (asked_a_question && started_a_discussion) || received_notification?(discuss_and_ask_broadcast) + return if + user.created_at > 6.days.ago || + (asked_a_question && started_a_discussion) || + received_notification?(discuss_and_ask_broadcast) Notification.send_welcome_notification(user.id, discuss_and_ask_broadcast.id) @notification_enqueued = true diff --git a/app/services/credits/ledger.rb b/app/services/credits/ledger.rb index 850c26142..0b25c2776 100644 --- a/app/services/credits/ledger.rb +++ b/app/services/credits/ledger.rb @@ -51,7 +51,9 @@ module Credits # to avoid N+1 on purchases, we load them by type separately purchase_types = credits_purchases_with_purchase.map(&:purchase_type).uniq.compact purchase_types.each do |purchase_type| - credits_purchases_by_type = credits_purchases_with_purchase.select { |row| row.purchase_type == purchase_type } + credits_purchases_by_type = credits_purchases_with_purchase.select do |row| + row.purchase_type == purchase_type + end purchase_set = purchase_type.constantize.where(id: credits_purchases_by_type.map(&:purchase_id)) credits_purchases_by_type.each do |credit_purchase| purchase = purchase_set.detect { |set| set.id == credit_purchase.purchase_id } diff --git a/app/services/mentions/create_all.rb b/app/services/mentions/create_all.rb index 294dc02b1..c184fefda 100644 --- a/app/services/mentions/create_all.rb +++ b/app/services/mentions/create_all.rb @@ -63,7 +63,8 @@ module Mentions def create_mention_for(user) return if user_has_comment_notifications?(user) - mention = Mention.create(user_id: user.id, mentionable_id: @notifiable.id, mentionable_type: @notifiable.class.name) + mention = Mention.create(user_id: user.id, mentionable_id: @notifiable.id, + mentionable_type: @notifiable.class.name) # mentionable_type = model that created the mention, user = user to be mentioned Notification.send_mention_notification(mention) mention diff --git a/app/services/moderator/banish_user.rb b/app/services/moderator/banish_user.rb index b8283f2b3..7375f665a 100644 --- a/app/services/moderator/banish_user.rb +++ b/app/services/moderator/banish_user.rb @@ -33,7 +33,8 @@ module Moderator new_name = "spam_#{rand(1_000_000)}" new_username = "spam_#{rand(1_000_000)}" end - user.update_columns(name: new_name, username: new_username, old_username: user.username, profile_updated_at: Time.current) + user.update_columns(name: new_name, username: new_username, old_username: user.username, + profile_updated_at: Time.current) CacheBuster.bust("/#{user.old_username}") end @@ -42,7 +43,8 @@ module Moderator twitter_username: nil, github_username: nil, website_url: "", summary: "", location: "", education: "", employer_name: "", employer_url: "", employment_title: "", mostly_work_with: "", currently_learning: "", currently_hacking_on: "", available_for: "", - email_public: false, facebook_url: nil, youtube_url: nil, dribbble_url: nil, medium_url: nil, stackoverflow_url: nil, + email_public: false, facebook_url: nil, youtube_url: nil, dribbble_url: nil, + medium_url: nil, stackoverflow_url: nil, behance_url: nil, linkedin_url: nil, gitlab_url: nil, instagram_url: nil, mastodon_url: nil, twitch_url: nil, feed_url: nil ) diff --git a/app/services/moderator/merge_user.rb b/app/services/moderator/merge_user.rb index 7b1cdecc2..a1a4be9b1 100644 --- a/app/services/moderator/merge_user.rb +++ b/app/services/moderator/merge_user.rb @@ -31,9 +31,15 @@ module Moderator private def handle_identities - raise "The user being deleted already has two identities. Are you sure this is the right user to be deleted? If so, a super admin will need to do this from the console to be safe." if @delete_user.identities.count > 1 + error_message = "The user being deleted already has two identities. " \ + "Are you sure this is the right user to be deleted? " \ + "If so, a super admin will need to do this from the console to be safe." + raise error_message if @delete_user.identities.count.positive? - return true if @keep_user.identities.count > 1 || @delete_user.identities.none? || @keep_user.identities.last.provider == @delete_user.identities.last.provider + return true if + @keep_user.identities.count.positive? || + @delete_user.identities.none? || + @keep_user.identities.last.provider == @delete_user.identities.last.provider @delete_user.identities.first.update_columns(user_id: @keep_user.id) end @@ -63,7 +69,8 @@ module Moderator end def merge_chat_mentions - @delete_user.chat_channel_memberships.update_all(user_id: @keep_user.id) if @delete_user.chat_channel_memberships.any? + any_memberships = @delete_user.chat_channel_memberships.any? + @delete_user.chat_channel_memberships.update_all(user_id: @keep_user.id) if any_memberships @delete_user.mentions.update_all(user_id: @keep_user.id) if @delete_user.mentions.any? end diff --git a/app/services/notifications/notifiable_action/send.rb b/app/services/notifications/notifiable_action/send.rb index dcc04330d..2f5c579df 100644 --- a/app/services/notifications/notifiable_action/send.rb +++ b/app/services/notifications/notifiable_action/send.rb @@ -55,7 +55,12 @@ module Notifications def followers followers = notifiable.user.followers_scoped.where(subscription_status: "all_articles").map(&:follower) - followers += notifiable.organization.followers_scoped.where(subscription_status: "all_articles").map(&:follower) if notifiable.organization_id + + if notifiable.organization_id + org_followers = notifiable.organization.followers_scoped.where(subscription_status: "all_articles") + followers += org_followers.map(&:follower) + end + followers.uniq.compact end diff --git a/app/services/notifications/reactions/send.rb b/app/services/notifications/reactions/send.rb index b92e24374..1587e92f6 100644 --- a/app/services/notifications/reactions/send.rb +++ b/app/services/notifications/reactions/send.rb @@ -22,12 +22,15 @@ module Notifications def call return unless receiver.is_a?(User) || receiver.is_a?(Organization) - reaction_siblings = Reaction.public_category.where(reactable_id: reaction.reactable_id, reactable_type: reaction.reactable_type). + reaction_siblings = Reaction.public_category.where(reactable_id: reaction.reactable_id, + reactable_type: reaction.reactable_type). where.not(reactions: { user_id: reaction.reactable_user_id }). preload(:reactable).includes(:user).where.not(users: { id: nil }). order("reactions.created_at DESC") - aggregated_reaction_siblings = reaction_siblings.map { |reaction| { category: reaction.category, created_at: reaction.created_at, user: user_data(reaction.user) } } + aggregated_reaction_siblings = reaction_siblings.map do |reaction| + { category: reaction.category, created_at: reaction.created_at, user: user_data(reaction.user) } + end notification_params = { notifiable_type: reaction.reactable_type, @@ -50,7 +53,10 @@ module Notifications previous_siblings_size = 0 notification = Notification.find_or_initialize_by(notification_params) - previous_siblings_size = notification.json_data["reaction"]["aggregated_siblings"].size if notification.json_data + + old_json_data = notification.json_data + previous_siblings_size = notification.json_data["reaction"]["aggregated_siblings"].size if old_json_data + notification.json_data = json_data notification.notified_at = Time.current notification.read = false if json_data[:reaction][:aggregated_siblings].size > previous_siblings_size diff --git a/app/services/search/chat_channel_membership.rb b/app/services/search/chat_channel_membership.rb index 42cf1b8ae..ef6533332 100644 --- a/app/services/search/chat_channel_membership.rb +++ b/app/services/search/chat_channel_membership.rb @@ -2,7 +2,8 @@ module Search class ChatChannelMembership < Base INDEX_NAME = "chat_channel_memberships_#{Rails.env}".freeze INDEX_ALIAS = "chat_channel_memberships_#{Rails.env}_alias".freeze - MAPPINGS = JSON.parse(File.read("config/elasticsearch/mappings/chat_channel_memberships.json"), symbolize_names: true).freeze + MAPPINGS = JSON.parse(File.read("config/elasticsearch/mappings/chat_channel_memberships.json"), + symbolize_names: true).freeze DEFAULT_PAGE = 0 DEFAULT_PER_PAGE = 30 diff --git a/app/services/streams/twitch_webhook/register.rb b/app/services/streams/twitch_webhook/register.rb index 51f96ed9a..03c4a4b1d 100644 --- a/app/services/streams/twitch_webhook/register.rb +++ b/app/services/streams/twitch_webhook/register.rb @@ -13,7 +13,8 @@ module Streams end def call - user_resp = HTTParty.get("https://api.twitch.tv/helix/users", query: { login: user.twitch_username }, headers: authentication_request_headers) + user_resp = HTTParty.get("https://api.twitch.tv/helix/users", query: { login: user.twitch_username }, + headers: authentication_request_headers) # user_resp["data"].first["id"] twitch_user_id = user_resp.try(:[], "data").to_a.first.try(:[], "id") @@ -45,7 +46,8 @@ module Streams end def twitch_stream_updates_url_for_user(user) - Rails.application.routes.url_helpers.user_twitch_stream_updates_url(user_id: user.id, host: ApplicationConfig["APP_DOMAIN"]) + Rails.application.routes.url_helpers.user_twitch_stream_updates_url(user_id: user.id, + host: ApplicationConfig["APP_DOMAIN"]) end end end diff --git a/app/services/tag_adjustment_creation_service.rb b/app/services/tag_adjustment_creation_service.rb index c65fdf690..a533564c3 100644 --- a/app/services/tag_adjustment_creation_service.rb +++ b/app/services/tag_adjustment_creation_service.rb @@ -27,7 +27,8 @@ class TagAdjustmentCreationService article.update!(tag_list: article.tag_list.remove(removed_tags)) end - article.update!(tag_list: article.tag_list.add(@tag_adjustment.tag_name)) if @tag_adjustment.adjustment_type == "addition" + update_tag_list = @tag_adjustment.adjustment_type == "addition" + article.update!(tag_list: article.tag_list.add(@tag_adjustment.tag_name)) if update_tag_list end def creation_args diff --git a/app/services/user_subscriptions/is_subscribed_cache_checker.rb b/app/services/user_subscriptions/is_subscribed_cache_checker.rb index 632ba3c99..2bc3d2ba1 100644 --- a/app/services/user_subscriptions/is_subscribed_cache_checker.rb +++ b/app/services/user_subscriptions/is_subscribed_cache_checker.rb @@ -15,7 +15,8 @@ module UserSubscriptions end def call - cache_key = "user-#{user.id}-#{user.updated_at.rfc3339}-#{user.subscribed_to_user_subscriptions_count}/is_subscribed_#{source_type}_#{source_id}" + cache_key = "user-#{user.id}-#{user.updated_at.rfc3339}-#{user.subscribed_to_user_subscriptions_count}/" \ + "is_subscribed_#{source_type}_#{source_id}" Rails.cache.fetch(cache_key, expires_in: 24.hours) do UserSubscription.where( subscriber_id: user.id, diff --git a/app/workers/metrics/record_daily_usage_worker.rb b/app/workers/metrics/record_daily_usage_worker.rb index 8c1734ad7..e5b654f0f 100644 --- a/app/workers/metrics/record_daily_usage_worker.rb +++ b/app/workers/metrics/record_daily_usage_worker.rb @@ -6,11 +6,21 @@ module Metrics def perform # Articles published in the past 24 hours with at least 15 "score" (positive/negative reactions) articles_min_15_score_past_24h = Article.published.where("score >= ? AND published_at > ?", 15, 1.day.ago).size - DatadogStatsClient.count("articles.min_15_score_past_24h", articles_min_15_score_past_24h, tags: ["resource:articles"]) + DatadogStatsClient.count( + "articles.min_15_score_past_24h", + articles_min_15_score_past_24h, + tags: ["resource:articles"], + ) # Articles published in the past 24 hours with at least 15 "score" (positive/negative reactions) - articles_min_15_comment_score_past_24h = Article.published.where("comment_score >= ? AND published_at > ?", 15, 1.day.ago).size - DatadogStatsClient.count("articles.min_15_comment_score_past_24h", articles_min_15_comment_score_past_24h, tags: ["resource:articles"]) + articles_min_15_comment_score_past_24h = Article.published. + where("comment_score >= ? AND published_at > ?", 15, 1.day.ago). + size + DatadogStatsClient.count( + "articles.min_15_comment_score_past_24h", + articles_min_15_comment_score_past_24h, + tags: ["resource:articles"], + ) # Articles published in the past 24 which were that user's first article first_articles_past_24h = Article.where(nth_published_by_author: 1).where("published_at > ?", 1.day.ago).size @@ -18,17 +28,27 @@ module Metrics # Users who signed up in the past 24 hours who have made at least 1 comment so far new_users_min_1_comment_past_24h = User.where("comments_count >= ? AND created_at > ?", 1, 24.hours.ago).size - DatadogStatsClient.count("users.new_min_1_comment_past_24h", new_users_min_1_comment_past_24h, tags: ["resource:users"]) + DatadogStatsClient.count( + "users.new_min_1_comment_past_24h", + new_users_min_1_comment_past_24h, + tags: ["resource:users"], + ) # Total negative reactions in the past 24 hours nagative_reactions_past_24h = Reaction.where("points < 0").where("created_at > ?", 1.day.ago).size DatadogStatsClient.count("reactions.negative_past_24h", nagative_reactions_past_24h, tags: ["resource:reactions"]) # Total abuse (etc.) reports in the past 24 hours - reports_past_24_hours = FeedbackMessage.where(category: ["spam", "other", "rude or vulgar", "harassment"]).where("created_at > ?", 1.day.ago).size - DatadogStatsClient.count("feedback_messages.reports_past_24_hours", reports_past_24_hours, tags: ["resource:feedback_messages"]) + categories = ["spam", "other", "rude or vulgar", "harassment"] + reports_past_24_hours = FeedbackMessage.where(category: categories).where("created_at > ?", 1.day.ago).size + DatadogStatsClient.count( + "feedback_messages.reports_past_24_hours", + reports_past_24_hours, + tags: ["resource:feedback_messages"], + ) - # Counts of total days active (1-7) in the past week, e.g. 5000 users visited once this week, 3500 visited twice, etc. + # Counts of total days active (1-7) in the past week, + # e.g. 5000 users visited once this week, 3500 visited twice, etc. get_days_active_past_week_counts end @@ -37,11 +57,16 @@ module Metrics def get_days_active_past_week_counts ids_by_day = [] 7.times do |i| - ids_by_day << PageView.where("created_at > ? AND created_at < ?", (i + 1).days.ago, i.days.ago).where.not(user_id: nil).pluck(:user_id).uniq + id = PageView. + where("created_at > ? AND created_at < ?", (i + 1).days.ago, i.days.ago). + where.not(user_id: nil). + pluck(:user_id).uniq + ids_by_day << id end flat_id_list = ids_by_day.flatten.uniq non_new_user_ids = User.where("created_at < ?", 7.days.ago).where(id: flat_id_list).pluck(:id) - new_user_ids = User.where("created_at > ? AND created_at < ?", 8.days.ago, 7.days.ago).where(id: flat_id_list).pluck(:id) + new_user_ids = User.where("created_at > ? AND created_at < ?", 8.days.ago, + 7.days.ago).where(id: flat_id_list).pluck(:id) record_active_days_of_group(ids_by_day, non_new_user_ids, "established") record_active_days_of_group(ids_by_day, new_user_ids, "new") end @@ -51,7 +76,8 @@ module Metrics distinct_user_values = user_ids_by_day.flatten.group_by(&:itself).transform_values(&:count).values distinct_counts = distinct_user_values.group_by(&:itself).transform_values(&:count) distinct_counts.each_key do |key| - DatadogStatsClient.count("users.active_days_past_week", distinct_counts[key], tags: ["resource:users", "group:#{group}", "day_count:#{key}"]) + DatadogStatsClient.count("users.active_days_past_week", distinct_counts[key], + tags: ["resource:users", "group:#{group}", "day_count:#{key}"]) end end end diff --git a/app/workers/metrics/record_data_counts_worker.rb b/app/workers/metrics/record_data_counts_worker.rb index 030504713..c442d4a6f 100644 --- a/app/workers/metrics/record_data_counts_worker.rb +++ b/app/workers/metrics/record_data_counts_worker.rb @@ -22,7 +22,8 @@ module Metrics else model::SEARCH_CLASS.document_count end - DatadogStatsClient.gauge("elasticsearch.document_count", document_count, tags: ["table_name:#{model.table_name}"]) + DatadogStatsClient.gauge("elasticsearch.document_count", document_count, + tags: ["table_name:#{model.table_name}"]) end end end diff --git a/app/workers/podcasts/get_episodes_worker.rb b/app/workers/podcasts/get_episodes_worker.rb index bf018cbaf..47833e68b 100644 --- a/app/workers/podcasts/get_episodes_worker.rb +++ b/app/workers/podcasts/get_episodes_worker.rb @@ -8,7 +8,8 @@ module Podcasts # * :podcast_id [Integer] # * :limit [Integer] (1_000) - number of episodes that will be fetched for this podcast # * :force_update [Integer] (false) - if set to true, existing episodes' urls will be re-checked - # the episodes' `https` and `reachable` fields will be updated accordingly if needed + # the episodes' `https` and `reachable` fields will be updated + # accordingly if needed def perform(podcast_data = {}) # Sidekiq turns arguments into Strings so the Ruby keyword argument sorcery doesn't work here # prevent any mismatch between String keys and Symbol keys diff --git a/app/workers/reactions/bust_reactable_cache_worker.rb b/app/workers/reactions/bust_reactable_cache_worker.rb index d62042832..b2761457b 100644 --- a/app/workers/reactions/bust_reactable_cache_worker.rb +++ b/app/workers/reactions/bust_reactable_cache_worker.rb @@ -8,11 +8,12 @@ module Reactions reaction = Reaction.find_by(id: reaction_id) return unless reaction&.reactable - CacheBuster.bust reaction.user.path + CacheBuster.bust(reaction.user.path) if reaction.reactable_type == "Article" - CacheBuster.bust "/reactions?article_id=#{reaction.reactable_id}" + CacheBuster.bust("/reactions?article_id=#{reaction.reactable_id}") elsif reaction.reactable_type == "Comment" - path = "/reactions?commentable_id=#{reaction.reactable.commentable_id}&commentable_type=#{reaction.reactable.commentable_type}" + path = "/reactions?commentable_id=#{reaction.reactable.commentable_id}&" \ + "commentable_type=#{reaction.reactable.commentable_type}" CacheBuster.bust(path) end end diff --git a/config/environments/development.rb b/config/environments/development.rb index 9d305ebc4..c5194099b 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -132,7 +132,9 @@ Rails.application.configure do # Check if there are any data update scripts to run during startup if %w[c console runner s server].include?(ENV["COMMAND"]) if DataUpdateScript.scripts_to_run? - raise "Data update scripts need to be run before you can start the application. Please run 'rails data_updates:run'" + message = "Data update scripts need to be run before you can start the application. " \ + "Please run 'rails data_updates:run'" + raise message end end end diff --git a/config/initializers/honeybadger.rb b/config/initializers/honeybadger.rb index f54952fe3..4e6297ec7 100644 --- a/config/initializers/honeybadger.rb +++ b/config/initializers/honeybadger.rb @@ -29,7 +29,9 @@ Honeybadger.configure do |config| config.before_notify do |notice| notice.fingerprint = if notice.error_message&.include?("SIGTERM") && notice.component&.include?("fetch_all_rss") notice.error_message - elsif (msg_key = MESSAGE_FINGERPRINTS.keys.detect { |k, _v| notice.error_message&.include?(k) }) + elsif (msg_key = MESSAGE_FINGERPRINTS.keys.detect do |k, _v| + notice.error_message&.include?(k) + end) MESSAGE_FINGERPRINTS[msg_key] elsif (cmp_key = COMPONENT_FINGERPRINTS.keys.detect { |k, _v| notice.component&.include?(k) }) COMPONENT_FINGERPRINTS[cmp_key] diff --git a/config/initializers/persistent_csrf_token_cookie.rb b/config/initializers/persistent_csrf_token_cookie.rb index a0306ee32..11f7cd466 100644 --- a/config/initializers/persistent_csrf_token_cookie.rb +++ b/config/initializers/persistent_csrf_token_cookie.rb @@ -32,5 +32,7 @@ end Warden::Manager.after_authentication do |_record, warden, _options| clean_up_for_winning_strategy = !warden.winning_strategy.respond_to?(:clean_up_csrf?) || warden.winning_strategy.clean_up_csrf? - warden.cookies.delete(ActionController::RequestForgeryProtection::COOKIE_NAME) if Devise.clean_up_csrf_token_on_authentication && clean_up_for_winning_strategy + + delete_cookie = Devise.clean_up_csrf_token_on_authentication && clean_up_for_winning_strategy + warden.cookies.delete(ActionController::RequestForgeryProtection::COOKIE_NAME) if delete_cookie end diff --git a/db/seeds.rb b/db/seeds.rb index 17508e414..40947d005 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -66,7 +66,8 @@ users_in_random_order = seeder.create_if_none(User, num_users) do twitter_username: Faker::Internet.username(specifier: name), email_comment_notifications: false, email_follower_notifications: false, - email: Faker::Internet.email(name: name, separators: "+", domain: Faker::Internet.domain_word.first(20)), # Emails limited to 50 characters + # Emails limited to 50 characters + email: Faker::Internet.email(name: name, separators: "+", domain: Faker::Internet.domain_word.first(20)), confirmed_at: Time.current, password: "password", ) @@ -255,16 +256,32 @@ end seeder.create_if_none(Broadcast) do broadcast_messages = { - set_up_profile: "Welcome to DEV! 👋 I'm Sloan, the community mascot and I'm here to help get you started. Let's begin by setting up your profile!", - welcome_thread: "Sloan here again! 👋 DEV is a friendly community. Why not introduce yourself by leaving a comment in the welcome thread!", - twitter_connect: "You're on a roll! 🎉 Do you have a Twitter account? Consider connecting it so we can @mention you if we share your post via our Twitter account @thePracticalDev.", - github_connect: "You're on a roll! 🎉 Do you have a GitHub account? Consider connecting it so you can pin any of your repos to your profile.", - customize_feed: "Hi, it's me again! 👋 Now that you're a part of the DEV community, let's focus on personalizing your content. You can start by following some tags to help customize your feed! 🎉", - customize_experience: "Sloan here! 👋 Did you know that that you can customize your DEV experience? Try changing your font and theme and find the best style for you!", - start_discussion: "Sloan here! 👋 I noticed that you haven't started a discussion yet. Starting a discussion is easy to do; just click on 'Write a Post' in the sidebar of the tag page to get started!", - ask_question: "Sloan here! 👋 I noticed that you haven't asked a question yet. Asking a question is easy to do; just click on 'Write a Post' in the sidebar of the tag page to get started!", - discuss_and_ask: "Sloan here! 👋 I noticed that you haven't asked a question or started a discussion yet. It's easy to do both of these; just click on 'Write a Post' in the sidebar of the tag page to get started!", - download_app: "Sloan here, with one last tip! 👋 Have you downloaded the DEV mobile app yet? Consider downloading it so you can access all of your favorite DEV content on the go!" + set_up_profile: "Welcome to DEV! 👋 I'm Sloan, the community mascot and I'm here to help get you started. " \ + "Let's begin by setting up your profile!", + welcome_thread: "Sloan here again! 👋 DEV is a friendly community. " \ + "Why not introduce yourself by leaving a comment in the welcome thread!", + twitter_connect: "You're on a roll! 🎉 Do you have a Twitter account? " \ + "Consider connecting it so we can @mention you if we share your post " \ + "via our Twitter account @thePracticalDev.", + github_connect: "You're on a roll! 🎉 Do you have a GitHub account? " \ + "Consider connecting it so you can pin any of your repos to your profile.", + customize_feed: "Hi, it's me again! 👋 Now that you're a part of the DEV community, let's focus on personalizing " \ + "your content. You can start by following some tags to help customize your feed! 🎉", + customize_experience: "Sloan here! 👋 Did you know that that you can customize your DEV experience? " \ + "Try changing your font and theme and find the best style for you!", + start_discussion: "Sloan here! 👋 I noticed that you haven't " \ + "started a discussion yet. Starting a discussion is easy to do; " \ + "just click on 'Write a Post' in the sidebar of the tag page to get started!", + ask_question: "Sloan here! 👋 I noticed that you haven't " \ + "asked a question yet. Asking a question is easy to do; " \ + "just click on 'Write a Post' in the sidebar of the tag page to get started!", + discuss_and_ask: "Sloan here! 👋 I noticed that you haven't " \ + "asked a question or " \ + "started a discussion yet. It's easy to do both of these; " \ + "just click on 'Write a Post' in the sidebar of the tag page to get started!", + download_app: "Sloan here, with one last tip! 👋 Have you downloaded the DEV mobile app yet? " \ + "Consider downloading it so you can access all " \ + "of your favorite DEV content on the go!" } broadcast_messages.each do |type, message| @@ -479,7 +496,8 @@ num_path_redirects = 2 * SEEDS_MULTIPLIER seeder.create_if_none(PathRedirect, num_path_redirects) do articles_for_old_paths = Article.where(published: true).order(Arel.sql("RANDOM()")).limit(num_path_redirects) - articles_for_new_paths = Article.where.not(id: articles_for_old_paths.map(&:id), published: false).order(Arel.sql("RANDOM()")).limit(num_path_redirects) + articles_for_new_paths = Article.where.not(id: articles_for_old_paths.map(&:id), + published: false).order(Arel.sql("RANDOM()")).limit(num_path_redirects) articles_for_old_paths.each_with_index do |old_article, i| new_article = articles_for_new_paths[i] diff --git a/lib/data_update_scripts/20200518173504_update_public_reactions_count_from_positive_reactions_count.rb b/lib/data_update_scripts/20200518173504_update_public_reactions_count_from_positive_reactions_count.rb index a78eb2ed9..b62deff21 100644 --- a/lib/data_update_scripts/20200518173504_update_public_reactions_count_from_positive_reactions_count.rb +++ b/lib/data_update_scripts/20200518173504_update_public_reactions_count_from_positive_reactions_count.rb @@ -1,7 +1,8 @@ module DataUpdateScripts class UpdatePublicReactionsCountFromPositiveReactionsCount def run - # ActiveRecord::Base.connection.execute("UPDATE articles SET public_reactions_count = positive_reactions_count, previous_public_reactions_count = previous_positive_reactions_count") + # ActiveRecord::Base.connection.execute("UPDATE articles SET public_reactions_count = positive_reactions_count, + # previous_public_reactions_count = previous_positive_reactions_count") # ActiveRecord::Base.connection.execute("UPDATE comments SET public_reactions_count = positive_reactions_count") end end diff --git a/lib/data_update_scripts/20200526181850_update_public_reaction_counts_again.rb b/lib/data_update_scripts/20200526181850_update_public_reaction_counts_again.rb index 627560be8..7bccf2b60 100644 --- a/lib/data_update_scripts/20200526181850_update_public_reaction_counts_again.rb +++ b/lib/data_update_scripts/20200526181850_update_public_reaction_counts_again.rb @@ -3,10 +3,20 @@ module DataUpdateScripts def run article_count = Article.count comment_count = Comment.count - ActiveRecord::Base.connection.execute("UPDATE articles SET public_reactions_count = positive_reactions_count, previous_public_reactions_count = previous_positive_reactions_count WHERE id <= #{article_count / 2}") - ActiveRecord::Base.connection.execute("UPDATE articles SET public_reactions_count = positive_reactions_count, previous_public_reactions_count = previous_positive_reactions_count WHERE id > #{article_count / 2}") - ActiveRecord::Base.connection.execute("UPDATE comments SET public_reactions_count = positive_reactions_count WHERE id <= #{comment_count / 2}") - ActiveRecord::Base.connection.execute("UPDATE comments SET public_reactions_count = positive_reactions_count WHERE id > #{comment_count / 2}") + ActiveRecord::Base.connection.execute( + "UPDATE articles SET public_reactions_count = positive_reactions_count, previous_public_reactions_count = " \ + "previous_positive_reactions_count WHERE id <= #{article_count / 2}", + ) + ActiveRecord::Base.connection.execute( + "UPDATE articles SET public_reactions_count = positive_reactions_count, previous_public_reactions_count = " \ + "previous_positive_reactions_count WHERE id > #{article_count / 2}", + ) + ActiveRecord::Base.connection.execute( + "UPDATE comments SET public_reactions_count = positive_reactions_count WHERE id <= #{comment_count / 2}", + ) + ActiveRecord::Base.connection.execute( + "UPDATE comments SET public_reactions_count = positive_reactions_count WHERE id > #{comment_count / 2}", + ) end end end diff --git a/lib/generators/data_update/data_update_generator.rb b/lib/generators/data_update/data_update_generator.rb index c259b2ee4..a85823e94 100644 --- a/lib/generators/data_update/data_update_generator.rb +++ b/lib/generators/data_update/data_update_generator.rb @@ -4,7 +4,8 @@ class DataUpdateGenerator < Rails::Generators::NamedBase def create_data_update_file template( "data_update.rb.tt", - File.join("lib", "data_update_scripts", class_path, "#{Time.current.utc.strftime('%Y%m%d%H%M%S')}_#{file_name}.rb"), + File.join("lib", "data_update_scripts", class_path, + "#{Time.current.utc.strftime('%Y%m%d%H%M%S')}_#{file_name}.rb"), ) end end diff --git a/spec/black_box/black_box_spec.rb b/spec/black_box/black_box_spec.rb index 7e55cc50e..b0f44cf46 100644 --- a/spec/black_box/black_box_spec.rb +++ b/spec/black_box/black_box_spec.rb @@ -28,7 +28,8 @@ RSpec.describe BlackBox, type: :black_box do end it "returns the lower correct value if article tagged with watercooler" do - article = build_stubbed(:article, score: 99, cached_tag_list: "hello, discuss, watercooler", published_at: Time.current) + article = build_stubbed(:article, score: 99, cached_tag_list: "hello, discuss, watercooler", + published_at: Time.current) allow(function_caller).to receive(:call).and_return(5) # recent bonuses (28 + 31 + 80 + 395 + 330 + 330 = 1194) # + score (99) diff --git a/spec/decorators/article_decorator_spec.rb b/spec/decorators/article_decorator_spec.rb index 1203240df..0b4f74c71 100644 --- a/spec/decorators/article_decorator_spec.rb +++ b/spec/decorators/article_decorator_spec.rb @@ -178,7 +178,8 @@ RSpec.describe ArticleDecorator, type: :decorator do it "returns search_optimized_description_replacement if it is present" do body_markdown = "---\ntitle: Title\npublished: false\ndescription:\ntags: heytag\n---\n\nHey this is the article" search_optimized_description_replacement = "Hey this is the expected result" - expect(create_article(body_markdown: body_markdown, search_optimized_description_replacement: search_optimized_description_replacement). + expect(create_article(body_markdown: body_markdown, + search_optimized_description_replacement: search_optimized_description_replacement). description_and_tags).to eq(search_optimized_description_replacement) end end diff --git a/spec/factories/backup_data.rb b/spec/factories/backup_data.rb index 9bad23b54..27124c955 100644 --- a/spec/factories/backup_data.rb +++ b/spec/factories/backup_data.rb @@ -2,7 +2,8 @@ FactoryBot.define do factory :backup_data do association :instance_user, factory: :user after(:build) do |backup_data| - backup_data.instance = backup_data.instance_user.identities.first || create(:identity, user: backup_data.instance_user) + backup_data.instance = backup_data.instance_user.identities.first || create(:identity, + user: backup_data.instance_user) backup_data.json_data = backup_data.instance.attributes end end diff --git a/spec/factories/broadcasts.rb b/spec/factories/broadcasts.rb index 9f3791705..876a10017 100644 --- a/spec/factories/broadcasts.rb +++ b/spec/factories/broadcasts.rb @@ -6,61 +6,100 @@ FactoryBot.define do factory :set_up_profile_broadcast do title { "Welcome Notification: set_up_profile" } type_of { "Welcome" } - processed_html { "Welcome to DEV! 👋 I'm Sloan, the community mascot and I'm here to help get you started. Let's begin by setting up your profile!" } + processed_html do + "Welcome to DEV! 👋 I'm Sloan, " \ + "the community mascot and I'm here to help get you started. " \ + "Let's begin by setting up your profile!" + end end factory :welcome_broadcast do title { "Welcome Notification: welcome_thread" } type_of { "Welcome" } - processed_html { "Sloan here again! 👋 DEV is a friendly community. Why not introduce yourself by leaving a comment in the welcome thread!" } + processed_html do + "Sloan here again! 👋 DEV is a friendly community. " \ + "Why not introduce yourself by leaving a comment in the welcome thread!" + end end factory :twitter_connect_broadcast do title { "Welcome Notification: twitter_connect" } type_of { "Welcome" } - processed_html { "You're on a roll! 🎉 Do you have a Twitter account? Consider connecting it so we can @mention you if we share your post via our Twitter account @thePracticalDev." } + processed_html do + "You're on a roll! 🎉 Do you have a Twitter account? Consider " \ + "connecting it so we can @mention you if we share " \ + "your post via our Twitter account @thePracticalDev." + end end factory :github_connect_broadcast do title { "Welcome Notification: github_connect" } type_of { "Welcome" } - processed_html { "You're on a roll! 🎉 Do you have a GitHub account? Consider connecting it so you can pin any of your repos to your profile." } + processed_html do + "You're on a roll! 🎉 Do you have a GitHub account? Consider " \ + "connecting it so you can pin any of your repos to your profile." + end end factory :customize_ux_broadcast do title { "Welcome Notification: customize_experience" } type_of { "Welcome" } - processed_html { "Sloan here! 👋 Did you know that that you can customize your DEV experience? Try changing your font and theme and find the best style for you!" } + processed_html do + "Sloan here! 👋 Did you know that that you can customize your DEV experience? " \ + "Try changing your font and theme and find the best style for you!" + end end factory :customize_feed_broadcast do title { "Welcome Notification: customize_feed" } type_of { "Welcome" } - processed_html { "Hi, it's me again! 👋 Now that you're a part of the DEV community, let's focus on personalizing your content. You can start by following some tags to help customize your feed! 🎉" } + processed_html do + "Hi, it's me again! 👋 Now that you're a part of the DEV community, " \ + "let's focus on personalizing your content. You can start by " \ + "following some tags to help customize your feed! 🎉" + end end factory :start_discussion_broadcast do title { "Welcome Notification: start_discussion" } type_of { "Welcome" } - processed_html { "Sloan here! 👋 I noticed that you haven't started a discussion yet. Starting a discussion is easy to do; just click on 'Write a Post' in the sidebar of the tag page to get started!" } + processed_html do + "Sloan here! 👋 I noticed that you haven't " \ + "started a discussion yet. " \ + "Starting a discussion is easy to do; just click on 'Write a Post' " \ + "in the sidebar of the tag page to get started!" + end end factory :ask_question_broadcast do title { "Welcome Notification: ask_question" } type_of { "Welcome" } - processed_html { "Sloan here! 👋 I noticed that you haven't asked a question yet. Asking a question is easy to do; just click on 'Write a Post' in the sidebar of the tag page to get started!" } + processed_html do + "Sloan here! 👋 I noticed that you haven't " \ + "asked a question yet. " \ + "Asking a question is easy to do; just click on 'Write a Post' in the sidebar of the tag page to get started!" + end end factory :discuss_and_ask_broadcast do title { "Welcome Notification: discuss_and_ask" } type_of { "Welcome" } - processed_html { "Sloan here! 👋 I noticed that you haven't asked a question or started a discussion yet. It's easy to do both of these; just click on 'Write a Post' in the sidebar of the tag page to get started!" } + processed_html do + "Sloan here! 👋 I noticed that you haven't " \ + "asked a question or " \ + "started a discussion yet. " \ + "It's easy to do both of these; just click on 'Write a Post' in the sidebar of the tag page to get started!" + end end factory :download_app_broadcast do title { "Welcome Notification: download_app" } type_of { "Welcome" } - processed_html { "Sloan here, with one last tip! 👋 Have you downloaded the DEV mobile app yet? Consider downloading it so you can access all of your favorite DEV content on the go!" } + processed_html do + "Sloan here, with one last tip! 👋 Have you downloaded the DEV mobile " \ + "app yet? Consider downloading it " \ + "so you can access all of your favorite DEV content on the go!" + end end factory :announcement_broadcast do @@ -70,7 +109,10 @@ FactoryBot.define do end trait :with_tracking do - processed_html { "Sloan here again! 👋 DEV is a friendly community. Why not introduce yourself by leaving a comment in the welcome thread!" } + processed_html do + "Sloan here again! 👋 DEV is a friendly community. Why not introduce " \ + "yourself by leaving a comment in the welcome thread!" + end end end end diff --git a/spec/factories/organization_memberships.rb b/spec/factories/organization_memberships.rb index 4d6c8f455..5c756fcfb 100644 --- a/spec/factories/organization_memberships.rb +++ b/spec/factories/organization_memberships.rb @@ -5,7 +5,8 @@ FactoryBot.define do type_of_user { "member" } after(:build) do |organization_membership| - organization_membership.class.skip_callback(:create, :after, :update_user_organization_info_updated_at, raise: false) + organization_membership.class.skip_callback(:create, :after, :update_user_organization_info_updated_at, + raise: false) end end end diff --git a/spec/factories/user_subscription.rb b/spec/factories/user_subscription.rb index 8f0219739..1a3874c13 100644 --- a/spec/factories/user_subscription.rb +++ b/spec/factories/user_subscription.rb @@ -1,7 +1,11 @@ FactoryBot.define do factory :user_subscription do association :subscriber, factory: :user, strategy: :create - association :user_subscription_sourceable, factory: %i[article with_user_subscription_tag_role_user], with_user_subscription_tag: true + association( + :user_subscription_sourceable, + factory: %i[article with_user_subscription_tag_role_user], + with_user_subscription_tag: true, + ) author { user_subscription_sourceable.user } subscriber_email { subscriber.email } diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index a1177c337..e9786c1cc 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -144,7 +144,9 @@ RSpec.describe ApplicationHelper, type: :helper do body: "This is a longer body with a question mark ? \n and a newline" } - expect(email_link(text: "text", additional_info: additional_info)).to eq("text") + link = "text" + expect(email_link(text: "text", additional_info: additional_info)).to eq(link) end end diff --git a/spec/helpers/feedback_messages_helper_spec.rb b/spec/helpers/feedback_messages_helper_spec.rb index 950593cd7..519ac12ab 100644 --- a/spec/helpers/feedback_messages_helper_spec.rb +++ b/spec/helpers/feedback_messages_helper_spec.rb @@ -3,19 +3,28 @@ require "rails_helper" RSpec.describe FeedbackMessagesHelper, type: :helper do describe "#offender_email_details" do it "have proper subject and body" do - expect(helper.offender_email_details).to include(subject: "#{ApplicationConfig['COMMUNITY_NAME']} Code of Conduct Violation", body: a_string_starting_with("Hello")) + expect(helper.offender_email_details).to include( + subject: "#{ApplicationConfig['COMMUNITY_NAME']} Code of Conduct Violation", + body: a_string_starting_with("Hello"), + ) end end describe "#reporter_email_details" do it "have proper subject and body" do - expect(helper.reporter_email_details).to include(subject: "#{ApplicationConfig['COMMUNITY_NAME']} Report", body: a_string_starting_with("Hi")) + expect(helper.reporter_email_details).to include( + subject: "#{ApplicationConfig['COMMUNITY_NAME']} Report", + body: a_string_starting_with("Hi"), + ) end end describe "#affected_email_details" do it "have proper subject and body" do - expect(helper.affected_email_details).to include(subject: "Courtesy Notice from #{ApplicationConfig['COMMUNITY_NAME']}", body: a_string_starting_with("Hi")) + expect(helper.affected_email_details).to include( + subject: "Courtesy Notice from #{ApplicationConfig['COMMUNITY_NAME']}", + body: a_string_starting_with("Hi"), + ) end end end diff --git a/spec/initializers/rack/attack_spec.rb b/spec/initializers/rack/attack_spec.rb index 65224a0f3..ae4fd93e7 100644 --- a/spec/initializers/rack/attack_spec.rb +++ b/spec/initializers/rack/attack_spec.rb @@ -50,8 +50,10 @@ describe Rack::Attack, type: :request, throttle: true do let(:another_api_secret) { create(:api_secret) } it "throttles api write endpoints based on IP and API key" do - headers = { "api-key" => api_secret.secret, "content-type" => "application/json", "HTTP_FASTLY_CLIENT_IP" => "5.6.7.8" } - dif_headers = { "api-key" => another_api_secret.secret, "content-type" => "application/json", "HTTP_FASTLY_CLIENT_IP" => "5.6.7.8" } + headers = { "api-key" => api_secret.secret, "content-type" => "application/json", + "HTTP_FASTLY_CLIENT_IP" => "5.6.7.8" } + dif_headers = { "api-key" => another_api_secret.secret, "content-type" => "application/json", + "HTTP_FASTLY_CLIENT_IP" => "5.6.7.8" } params = { article: { body_markdown: "", title: Faker::Book.title } }.to_json Timecop.freeze do diff --git a/spec/labor/color_from_image_spec.rb b/spec/labor/color_from_image_spec.rb index e2d6d0f55..c8ddc5269 100644 --- a/spec/labor/color_from_image_spec.rb +++ b/spec/labor/color_from_image_spec.rb @@ -2,7 +2,9 @@ require "rails_helper" RSpec.describe ColorFromImage, type: :labor do it "returns a color" do + color = described_class.new(File.expand_path("spec/fixtures/files/image_gps_data.jpg")).main + expected_regexp = /\A#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/ - expect(described_class.new(File.expand_path("spec/fixtures/files/image_gps_data.jpg")).main).to match expected_regexp + expect(color).to match(expected_regexp) end end diff --git a/spec/labor/language_detector_spec.rb b/spec/labor/language_detector_spec.rb index ed82a8b0d..77ce2613d 100644 --- a/spec/labor/language_detector_spec.rb +++ b/spec/labor/language_detector_spec.rb @@ -19,8 +19,10 @@ RSpec.describe LanguageDetector, type: :labor do end it "detects nil if non-sensicle" do - article_2.update_column(:body_markdown, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec pharetra sapien orci, sit amet auctor nunc tempor quis.") - article_2.update_column(:title, "Mauris commodo felis et lacus volutpat fermentum.") - expect(described_class.new(article_2).detect).to eq(nil) + body = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " \ + "Donec pharetra sapien orci, sit amet auctor nunc tempor quis." + article_2.update_columns(body_markdown: body, title: "Mauris commodo felis et lacus volutpat fermentum.") + + expect(described_class.new(article_2).detect).to be(nil) end end diff --git a/spec/labor/mailchimp_bot_spec.rb b/spec/labor/mailchimp_bot_spec.rb index bb3ca6971..1a769c7c8 100644 --- a/spec/labor/mailchimp_bot_spec.rb +++ b/spec/labor/mailchimp_bot_spec.rb @@ -22,7 +22,10 @@ RSpec.describe MailchimpBot, type: :labor do let(:user) { create(:user, :ignore_mailchimp_subscribe_callback) } let(:article) { create(:article, user_id: user.id) } let(:my_gibbon_client) { instance_double(FakeGibbonRequest) } - let(:tag) { create(:tag, name: "tagname", bg_color_hex: Faker::Color.hex_color, text_color_hex: Faker::Color.hex_color, supported: true) } + let(:tag) do + create(:tag, name: "tagname", bg_color_hex: Faker::Color.hex_color, text_color_hex: Faker::Color.hex_color, + supported: true) + end before do allow(Gibbon::Request).to receive(:new) { my_gibbon_client } diff --git a/spec/labor/markdown_parser_spec.rb b/spec/labor/markdown_parser_spec.rb index ca07dd521..cc9492e88 100644 --- a/spec/labor/markdown_parser_spec.rb +++ b/spec/labor/markdown_parser_spec.rb @@ -140,7 +140,11 @@ RSpec.describe MarkdownParser, type: :labor do - `@#{user.username}` DOC result = generate_and_parse_markdown(mention) - expect(result).to eq("

@#{user.username} one two, @#{user.username}\n three four:

\n\n\n\n") + + expected_result = "

@#{user.username} one two, " \ + "@#{user.username}\n three four:

\n\n\n\n" + expect(result).to eq(expected_result) end it "will not work in code tag" do diff --git a/spec/lib/html_css_to_image_spec.rb b/spec/lib/html_css_to_image_spec.rb index fdf00de2b..d13a83a01 100644 --- a/spec/lib/html_css_to_image_spec.rb +++ b/spec/lib/html_css_to_image_spec.rb @@ -33,7 +33,8 @@ RSpec.describe HtmlCssToImage, type: :lib do body: '{ "url": "https://hcti.io/v1/image/6c52de9d-4d37-4008-80f8-67155589e1a1" }', headers: { "Content-Type" => "application/json" }) - expect(described_class.fetch_url(html: "test")).to eq("https://hcti.io/v1/image/6c52de9d-4d37-4008-80f8-67155589e1a1") + expected_url = "https://hcti.io/v1/image/6c52de9d-4d37-4008-80f8-67155589e1a1" + expect(described_class.fetch_url(html: "test")).to eq(expected_url) expect(Rails.cache).to have_received(:write).once end @@ -44,8 +45,10 @@ RSpec.describe HtmlCssToImage, type: :lib do body: '{ "url": "https://hcti.io/v1/image/6c52de9d-4d37-4008-80f8-67155589e1a1" }', headers: { "Content-Type" => "application/json" }) - expect(described_class.fetch_url(html: "test")).to eq("https://hcti.io/v1/image/6c52de9d-4d37-4008-80f8-67155589e1a1") - expect(Rails.cache).to have_received(:write).with(anything, anything, expires_in: HtmlCssToImage::CACHE_EXPIRATION).once + expected_url = "https://hcti.io/v1/image/6c52de9d-4d37-4008-80f8-67155589e1a1" + expect(described_class.fetch_url(html: "test")).to eq(expected_url) + expect(Rails.cache).to have_received(:write). + with(anything, anything, expires_in: HtmlCssToImage::CACHE_EXPIRATION).once end it "does not cache errors" do diff --git a/spec/lib/sidekiq/honeycomb_middleware_spec.rb b/spec/lib/sidekiq/honeycomb_middleware_spec.rb index 1cbf2fc94..80d056054 100644 --- a/spec/lib/sidekiq/honeycomb_middleware_spec.rb +++ b/spec/lib/sidekiq/honeycomb_middleware_spec.rb @@ -31,7 +31,9 @@ RSpec.describe Sidekiq::HoneycombMiddleware do TestSidekiqWorker.perform_async("dont fail") end - collected_data = Honeycomb.libhoney.events.map(&:data).detect { |h| h["sidekiq.args"] == expected_hash["sidekiq.args"] } + collected_data = Honeycomb.libhoney.events.map(&:data).detect do |h| + h["sidekiq.args"] == expected_hash["sidekiq.args"] + end expect(collected_data).to include(expected_hash) end @@ -51,7 +53,9 @@ RSpec.describe Sidekiq::HoneycombMiddleware do TestSidekiqWorker.perform_async end - collected_data = Honeycomb.libhoney.events.map(&:data).detect { |h| h["sidekiq.args"] == expected_hash["sidekiq.args"] } + collected_data = Honeycomb.libhoney.events.map(&:data).detect do |h| + h["sidekiq.args"] == expected_hash["sidekiq.args"] + end expect(collected_data).to include(expected_hash) end end @@ -73,7 +77,9 @@ RSpec.describe Sidekiq::HoneycombMiddleware do expect { TestSidekiqWorker.perform_async("fail") }.to raise_error(StandardError) end - collected_data = Honeycomb.libhoney.events.map(&:data).detect { |h| h["sidekiq.args"] == error_hash["sidekiq.args"] } + collected_data = Honeycomb.libhoney.events.map(&:data).detect do |h| + h["sidekiq.args"] == error_hash["sidekiq.args"] + end expect(collected_data).to include(error_hash) end end diff --git a/spec/liquid_tags/codesandbox_tag_spec.rb b/spec/liquid_tags/codesandbox_tag_spec.rb index 0ee907c79..f276c780f 100644 --- a/spec/liquid_tags/codesandbox_tag_spec.rb +++ b/spec/liquid_tags/codesandbox_tag_spec.rb @@ -7,13 +7,19 @@ RSpec.describe CodesandboxTag, type: :liquid_tag do let(:valid_id_with_module) { "28qvv1wvxr module=/path/to/module.html" } let(:valid_id_with_view) { "28qvv1wvxr view=editor" } let(:valid_id_with_runonclick) { "28qvv1wvxr runonclick=1" } - let(:valid_id_with_initialpath_and_module) { "43lkjfdauf initialpath=/initial-path/file.js module=/path/to/module.html" } + let(:valid_id_with_initialpath_and_module) do + "43lkjfdauf initialpath=/initial-path/file.js module=/path/to/module.html" + end let(:valid_id_with_initialpath_and_view) { "43lkjfdauf initialpath=/initial-path/file.js view=split" } let(:valid_id_with_runonclick_and_module) { "43lkjfdauf runonclick=1 module=/path/to/module.html" } let(:valid_id_with_runonclick_and_view) { "28qvv1wvxr runonclick=1 view=preview" } let(:valid_id_with_initialpath_and_runonclick) { "43lkjfdauf initialpath=/initial-path/file.js runonclick=1" } - let(:valid_id_with_initialpath_and_module_and_runonclick) { "43lkjfdauf initialpath=/initial-path/file.js module=/path/to/module.html runonclick=1" } - let(:valid_id_with_initialpath_and_module_and_runonclick_and_view) { "43lkjfdauf initialpath=/initial-path/file.js module=/path/to/module.html runonclick=1 view=split" } + let(:valid_id_with_initialpath_and_module_and_runonclick) do + "43lkjfdauf initialpath=/initial-path/file.js module=/path/to/module.html runonclick=1" + end + let(:valid_id_with_initialpath_and_module_and_runonclick_and_view) do + "43lkjfdauf initialpath=/initial-path/file.js module=/path/to/module.html runonclick=1 view=split" + end let(:valid_id_with_special_characters) { "68jkfdsasa initialpath=/.@%_- module=-/%@._" } let(:bad_ids) do diff --git a/spec/liquid_tags/gist_tag_spec.rb b/spec/liquid_tags/gist_tag_spec.rb index 64c60d06c..8350ffcf5 100644 --- a/spec/liquid_tags/gist_tag_spec.rb +++ b/spec/liquid_tags/gist_tag_spec.rb @@ -21,7 +21,9 @@ RSpec.describe GistTag, type: :liquid_tag do let(:gist_link) { "https://gist.github.com/amochohan/8cb599ee5dc0af5f4246" } let(:link_with_file_option) { "#{gist_link} file=01_Laravel 5 Simple ACL manager_Readme.md" } - let(:gist_link_with_version) { "https://gist.github.com/suntong/3a31faf8129d3d7a380122d5a6d48ff6/44c4e7fa81592f917fffacf689dd76f469ca954c" } + let(:gist_link_with_version) do + "https://gist.github.com/suntong/3a31faf8129d3d7a380122d5a6d48ff6/44c4e7fa81592f917fffacf689dd76f469ca954c" + end def generate_new_liquid(link) Liquid::Template.register_tag("gist", GistTag) diff --git a/spec/liquid_tags/kotlin_tag_spec.rb b/spec/liquid_tags/kotlin_tag_spec.rb index 5aa1470e5..1049f4cdd 100644 --- a/spec/liquid_tags/kotlin_tag_spec.rb +++ b/spec/liquid_tags/kotlin_tag_spec.rb @@ -22,14 +22,26 @@ RSpec.describe KotlinTag, type: :liquid_tag do end def check(url, expected) - expect(KotlinTag.parse_link(url)).to eq(expected) + expect(described_class.parse_link(url)).to eq(expected) end it "parses URL correctly" do check("https://pl.kotl.in/owreUFFUG", from: nil, readOnly: nil, short: "owreUFFUG", theme: nil, to: nil) - check("https://pl.kotl.in/owreUFFUG?theme=dracula&from=3&to=6&readOnly=true", from: "3", readOnly: "true", short: "owreUFFUG", theme: "dracula", to: "6") - check("https://pl.kotl.in/owreUFFUG?theme=dracula&readOnly=true", from: nil, readOnly: "true", short: "owreUFFUG", theme: "dracula", to: nil) - check("https://pl.kotl.in/owreUFFUG?from=3&to=6", from: "3", readOnly: nil, short: "owreUFFUG", theme: nil, to: "6") + + check( + "https://pl.kotl.in/owreUFFUG?theme=dracula&from=3&to=6&readOnly=true", + from: "3", readOnly: "true", short: "owreUFFUG", theme: "dracula", to: "6", + ) + + check( + "https://pl.kotl.in/owreUFFUG?theme=dracula&readOnly=true", + from: nil, readOnly: "true", short: "owreUFFUG", theme: "dracula", to: nil, + ) + + check( + "https://pl.kotl.in/owreUFFUG?from=3&to=6", + from: "3", readOnly: nil, short: "owreUFFUG", theme: nil, to: "6", + ) end it "produces a correct final URL" do diff --git a/spec/liquid_tags/parler_tag_spec.rb b/spec/liquid_tags/parler_tag_spec.rb index b613b2a9e..47dbd8859 100644 --- a/spec/liquid_tags/parler_tag_spec.rb +++ b/spec/liquid_tags/parler_tag_spec.rb @@ -2,7 +2,9 @@ require "rails_helper" RSpec.describe ParlerTag, type: :liquid_tag do describe "#id" do - let(:valid_id) { "https://www.parler.io/audio/73240183203/d53cff009eac2ab1bc9dd8821a638823c39cbcea.7dd28611-b7fc-4cf8-9977-b6e3aaf644a1.mp3" } + let(:valid_id) do + "https://www.parler.io/audio/73240183203/d53cff009eac2ab1bc9dd8821a638823c39cbcea.7dd28611-b7fc-4cf8-9977-b6e3aaf644a1.mp3" + end let(:invalid_id) { "https://www.google.com" } diff --git a/spec/liquid_tags/reddit_tag_spec.rb b/spec/liquid_tags/reddit_tag_spec.rb index d96dfd45e..199614654 100644 --- a/spec/liquid_tags/reddit_tag_spec.rb +++ b/spec/liquid_tags/reddit_tag_spec.rb @@ -3,7 +3,9 @@ require "rails_helper" RSpec.describe RedditTag, type: :liquid_tag do context "when it is an image post" do describe "#render" do - let(:image_post) { "https://www.reddit.com/r/aww/comments/ag3s4b/ive_waited_28_years_to_finally_havr_my_first_pet" } + let(:image_post) do + "https://www.reddit.com/r/aww/comments/ag3s4b/ive_waited_28_years_to_finally_havr_my_first_pet" + end let(:response) do { "author" => "Miaogua007", @@ -46,12 +48,17 @@ RSpec.describe RedditTag, type: :liquid_tag do context "when it is a text post" do describe "#render" do - let(:text_post) { "https://www.reddit.com/r/IAmA/comments/afvl2w/im_scott_from_scotts_cheap_flights_my_profession" } + let(:text_post) do + "https://www.reddit.com/r/IAmA/comments/afvl2w/im_scott_from_scotts_cheap_flights_my_profession" + end + let(:response) do + post_url = "https://www.reddit.com/r/IAmA/comments/afvl2w/im_scott_from_scotts_cheap_flights_my_profession" + { "author" => "scottkeyes", "title" => "I'm Scott from Scott's C…r the next 8 hours. AMA", - "post_url" => "https://www.reddit.com/r/IAmA/comments/afvl2w/im_scott_from_scotts_cheap_flights_my_profession", + "post_url" => post_url, "created_utc" => 1_547_470_871, "post_hint" => "self", "image_url" => "", diff --git a/spec/liquid_tags/spotify_tag_spec.rb b/spec/liquid_tags/spotify_tag_spec.rb index db834b513..04492766a 100644 --- a/spec/liquid_tags/spotify_tag_spec.rb +++ b/spec/liquid_tags/spotify_tag_spec.rb @@ -45,7 +45,11 @@ RSpec.describe SpotifyTag, type: :liquid_tag do end it "raises an error if the uri is invalid" do - expect { generate_tag(invalid_uri) }.to raise_error(StandardError, "Invalid Spotify Link - Be sure you're using the uri of a specific track, album, artist, playlist, or podcast episode.") + message = "Invalid Spotify Link - Be sure you're using the uri of a specific track, " \ + "album, artist, playlist, or podcast episode." + expect do + generate_tag(invalid_uri) + end.to raise_error(StandardError, message) end end end diff --git a/spec/liquid_tags/stackery_tag_spec.rb b/spec/liquid_tags/stackery_tag_spec.rb index 75ae4b2b8..e99669a5c 100644 --- a/spec/liquid_tags/stackery_tag_spec.rb +++ b/spec/liquid_tags/stackery_tag_spec.rb @@ -17,7 +17,7 @@ RSpec.describe StackeryTag, type: :liquid_tag do it "renders valid input" do template = generate_tag(valid_input) - expected = "src=\"" + "//app.stackery.io/editor/design?owner=deeheber&repo=lambda-layer-example&ref=layer-resource" + expected = 'src="//app.stackery.io/editor/design?owner=deeheber&repo=lambda-layer-example&ref=layer-resource' expect(template.render(nil)).to include(expected) end diff --git a/spec/liquid_tags/user_subscription_tag_spec.rb b/spec/liquid_tags/user_subscription_tag_spec.rb index e3a4e7fb6..df2c9a273 100644 --- a/spec/liquid_tags/user_subscription_tag_spec.rb +++ b/spec/liquid_tags/user_subscription_tag_spec.rb @@ -5,7 +5,9 @@ RSpec.describe UserSubscriptionTag, type: :liquid_tag do let(:subscriber) { create(:user) } let(:author) { create(:user, :super_admin) } # TODO: (Alex Smith) - update roles before release - let(:article_with_user_subscription_tag) { create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true) } + let(:article_with_user_subscription_tag) do + create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true) + end context "when rendering" do it "renders default data correctly" do @@ -29,7 +31,8 @@ RSpec.describe UserSubscriptionTag, type: :liquid_tag do expect(page).to have_css("#subscriber-apple-auth", visible: :hidden) expect(page).to have_css("#response-message", visible: :hidden) expect(page).to have_css("#subscription-signed-out", visible: :visible) - expect(page).to have_css("img.ltag__user-subscription-tag__author-profile-image[src='#{author.profile_image_90}']") + css_class = "img.ltag__user-subscription-tag__author-profile-image[src='#{author.profile_image_90}']" + expect(page).to have_css(css_class) end end @@ -44,7 +47,8 @@ RSpec.describe UserSubscriptionTag, type: :liquid_tag do expect(page).to have_css("#subscriber-apple-auth", visible: :hidden) expect(page).to have_css("#response-message", visible: :hidden) expect(page).to have_css("#subscription-signed-in", visible: :visible) - expect(page).to have_css("img.ltag__user-subscription-tag__subscriber-profile-image[src='#{subscriber.profile_image_90}']") + css_class = "img.ltag__user-subscription-tag__subscriber-profile-image[src='#{subscriber.profile_image_90}']" + expect(page).to have_css(css_class) end it "asks the user to confirm their subscription" do @@ -70,7 +74,13 @@ RSpec.describe UserSubscriptionTag, type: :liquid_tag do it "displays errors when there's an error creating a subscription" do # Create a subscription so it causes an error by already being subscribed - create(:user_subscription, subscriber_id: subscriber.id, subscriber_email: subscriber.email, author_id: article_with_user_subscription_tag.user_id, user_subscription_sourceable: article_with_user_subscription_tag) + create( + :user_subscription, + subscriber_id: subscriber.id, subscriber_email: subscriber.email, + author_id: article_with_user_subscription_tag.user_id, + user_subscription_sourceable: article_with_user_subscription_tag + ) + expect(page).to have_css("#subscription-signed-out", visible: :hidden) expect(page).to have_css("#subscriber-apple-auth", visible: :hidden) expect(page).to have_css("#response-message", visible: :hidden) @@ -86,8 +96,15 @@ RSpec.describe UserSubscriptionTag, type: :liquid_tag do end it "tells the user they're already subscribed by default if they're already subscribed" do - create(:user_subscription, subscriber_id: subscriber.id, subscriber_email: subscriber.email, author_id: article_with_user_subscription_tag.user_id, user_subscription_sourceable: article_with_user_subscription_tag) + create( + :user_subscription, + subscriber_id: subscriber.id, subscriber_email: subscriber.email, + author_id: article_with_user_subscription_tag.user_id, + user_subscription_sourceable: article_with_user_subscription_tag + ) + visit article_with_user_subscription_tag.path + expect(page).to have_css("#subscription-signed-out", visible: :hidden) expect(page).to have_css("#subscription-signed-in", visible: :hidden) expect(page).to have_css("#subscriber-apple-auth", visible: :hidden) diff --git a/spec/mailers/digest_mailer_spec.rb b/spec/mailers/digest_mailer_spec.rb index fe2133e1d..66e9b4780 100644 --- a/spec/mailers/digest_mailer_spec.rb +++ b/spec/mailers/digest_mailer_spec.rb @@ -15,7 +15,8 @@ RSpec.describe DigestMailer, type: :mailer do expect(email.subject).not_to be_nil expect(email.to).to eq([user.email]) expect(email.from).to eq([SiteConfig.email_addresses[:default]]) - expect(email["from"].value).to eq("#{ApplicationConfig['COMMUNITY_NAME']} Digest <#{SiteConfig.email_addresses[:default]}>") + expected_from = "#{ApplicationConfig['COMMUNITY_NAME']} Digest <#{SiteConfig.email_addresses[:default]}>" + expect(email["from"].value).to eq(expected_from) end it "includes the tracking pixel" do diff --git a/spec/models/article_destroy_spec.rb b/spec/models/article_destroy_spec.rb index 01b385bbe..5acc5e768 100644 --- a/spec/models/article_destroy_spec.rb +++ b/spec/models/article_destroy_spec.rb @@ -24,7 +24,8 @@ RSpec.describe Article, type: :model do let!(:org_user_article) { create(:article, user: user, organization: organization) } it "queues BustCacheJob with user and organization article_ids" do - sidekiq_assert_enqueued_with(job: Articles::BustMultipleCachesWorker, args: [[user_article.id, org_user_article.id, org_article.id].sort]) do + sidekiq_assert_enqueued_with(job: Articles::BustMultipleCachesWorker, + args: [[user_article.id, org_user_article.id, org_article.id].sort]) do article.destroy end end diff --git a/spec/models/article_spec.rb b/spec/models/article_spec.rb index 92ff25d82..bbe63a949 100644 --- a/spec/models/article_spec.rb +++ b/spec/models/article_spec.rb @@ -41,7 +41,8 @@ RSpec.describe Article, type: :model do it "on destroy enqueues job to delete article from elasticsearch" do article = create(:article) - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [described_class::SEARCH_CLASS.to_s, article.search_id]) do + sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, + args: [described_class::SEARCH_CLASS.to_s, article.search_id]) do article.destroy end end diff --git a/spec/models/broadcast_spec.rb b/spec/models/broadcast_spec.rb index 86323400b..25e39a047 100644 --- a/spec/models/broadcast_spec.rb +++ b/spec/models/broadcast_spec.rb @@ -16,7 +16,8 @@ RSpec.describe Broadcast, type: :model do inactive_broadcast = build(:announcement_broadcast) expect(inactive_broadcast).not_to be_valid - expect(inactive_broadcast.errors.full_messages.join).to include("You can only have one active announcement broadcast") + expected_error_message = "You can only have one active announcement broadcast" + expect(inactive_broadcast.errors.full_messages.join).to include(expected_error_message) end it "updates the Broadcast's active_status_updated_at timestamp" do diff --git a/spec/models/chat_channel_membership_spec.rb b/spec/models/chat_channel_membership_spec.rb index ab0ea51a9..0422b132a 100644 --- a/spec/models/chat_channel_membership_spec.rb +++ b/spec/models/chat_channel_membership_spec.rb @@ -38,14 +38,16 @@ RSpec.describe ChatChannelMembership, type: :model do describe "#after_commit" do it "on update enqueues job to index chat_channel_membership to elasticsearch" do chat_channel_membership.save - sidekiq_assert_enqueued_with(job: Search::IndexWorker, args: [described_class.to_s, chat_channel_membership.id]) do + sidekiq_assert_enqueued_with(job: Search::IndexWorker, + args: [described_class.to_s, chat_channel_membership.id]) do chat_channel_membership.save end end it "on destroy enqueues job to delete chat_channel_membership from elasticsearch" do chat_channel_membership.save - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [described_class::SEARCH_CLASS.to_s, chat_channel_membership.id]) do + sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, + args: [described_class::SEARCH_CLASS.to_s, chat_channel_membership.id]) do chat_channel_membership.destroy end end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index fe711180d..cf3f3d456 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -47,7 +47,8 @@ RSpec.describe Comment, type: :model do it "on destroy enqueues job to delete comment from elasticsearch" do comment = create(:comment) - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [described_class::SEARCH_CLASS.to_s, comment.search_id]) do + sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, + args: [described_class::SEARCH_CLASS.to_s, comment.search_id]) do comment.destroy end end diff --git a/spec/models/concerns/searchable_spec.rb b/spec/models/concerns/searchable_spec.rb index 2347824d5..6c6f77483 100644 --- a/spec/models/concerns/searchable_spec.rb +++ b/spec/models/concerns/searchable_spec.rb @@ -31,7 +31,8 @@ RSpec.describe Searchable do describe "#remove_from_elasticsearch" do it "enqueues job to delete model document from elasticsearch" do - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [SearchableModel::SEARCH_CLASS.to_s, searchable_model.search_id]) do + sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, + args: [SearchableModel::SEARCH_CLASS.to_s, searchable_model.search_id]) do searchable_model.remove_from_elasticsearch end end @@ -49,7 +50,8 @@ RSpec.describe Searchable do it "indexes a document to elasticsearch inline" do allow(model_class::SEARCH_CLASS).to receive(:index) searchable_model.index_to_elasticsearch_inline - expect(model_class::SEARCH_CLASS).to have_received(:index).with(searchable_model.search_id, id: searchable_model.search_id) + expect(model_class::SEARCH_CLASS).to have_received(:index).with(searchable_model.search_id, + id: searchable_model.search_id) end end diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index 1502fbf75..776f23ed9 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -8,7 +8,12 @@ RSpec.describe Follow, type: :model do subject { user.follow(user_2) } it { is_expected.to validate_inclusion_of(:subscription_status).in_array(%w[all_articles none]) } - it { is_expected.to validate_uniqueness_of(:followable_id).scoped_to(%i[followable_type follower_id follower_type]) } + + # rubocop:disable RSpec/NamedSubject + it { + expect(subject).to validate_uniqueness_of(:followable_id).scoped_to(%i[followable_type follower_id follower_type]) + } + # rubocop:enable RSpec/NamedSubject end it "follows user" do diff --git a/spec/models/listing_spec.rb b/spec/models/listing_spec.rb index a8ed39884..cf1a95630 100644 --- a/spec/models/listing_spec.rb +++ b/spec/models/listing_spec.rb @@ -83,7 +83,8 @@ RSpec.describe Listing, type: :model do it "on destroy enqueues job to delete listing from elasticsearch" do listing.save - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [described_class::SEARCH_CLASS.to_s, listing.id]) do + sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, + args: [described_class::SEARCH_CLASS.to_s, listing.id]) do listing.destroy end end diff --git a/spec/models/path_redirect_spec.rb b/spec/models/path_redirect_spec.rb index 762a2beb4..c7eed1c80 100644 --- a/spec/models/path_redirect_spec.rb +++ b/spec/models/path_redirect_spec.rb @@ -13,7 +13,9 @@ RSpec.describe PathRedirect, type: :model do same_paths_path_redirect = build(:path_redirect, old_path: "/the-same-path", new_path: "/the-same-path") expect(same_paths_path_redirect).not_to be_valid - expect(same_paths_path_redirect.errors.full_messages.join).to include("the old_path cannot be the same as the new_path") + + expected_error_message = "the old_path cannot be the same as the new_path" + expect(same_paths_path_redirect.errors.full_messages.join).to include(expected_error_message) end it "validates new_path is not already being redirected" do diff --git a/spec/models/podcast_episode_spec.rb b/spec/models/podcast_episode_spec.rb index 00afb8c0c..93a35b988 100644 --- a/spec/models/podcast_episode_spec.rb +++ b/spec/models/podcast_episode_spec.rb @@ -39,7 +39,8 @@ RSpec.describe PodcastEpisode, type: :model do it "on destroy enqueues job to delete podcast_episode from elasticsearch" do podcast_episode.save - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [described_class::SEARCH_CLASS.to_s, podcast_episode.search_id]) do + sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, + args: [described_class::SEARCH_CLASS.to_s, podcast_episode.search_id]) do podcast_episode.destroy end end @@ -132,7 +133,8 @@ RSpec.describe PodcastEpisode, type: :model do context "when callbacks are triggered after save" do it "triggers cache busting on save" do - sidekiq_assert_enqueued_with(job: PodcastEpisodes::BustCacheWorker, args: [podcast_episode.id, podcast_episode.path, podcast_episode.podcast_slug]) do + sidekiq_assert_enqueued_with(job: PodcastEpisodes::BustCacheWorker, + args: [podcast_episode.id, podcast_episode.path, podcast_episode.podcast_slug]) do podcast_episode.save end end diff --git a/spec/models/reaction_spec.rb b/spec/models/reaction_spec.rb index d8511f07a..c9d710270 100644 --- a/spec/models/reaction_spec.rb +++ b/spec/models/reaction_spec.rb @@ -106,7 +106,8 @@ RSpec.describe Reaction, type: :model do it "on destroy enqueues job to delete reaction from elasticsearch" do reaction.category = "readinglist" reaction.save - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [described_class::SEARCH_CLASS.to_s, reaction.id]) do + sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, + args: [described_class::SEARCH_CLASS.to_s, reaction.id]) do reaction.destroy end end diff --git a/spec/models/response_template_spec.rb b/spec/models/response_template_spec.rb index f8ddedf24..72ba11a80 100644 --- a/spec/models/response_template_spec.rb +++ b/spec/models/response_template_spec.rb @@ -1,6 +1,8 @@ require "rails_helper" RSpec.describe ResponseTemplate, type: :model do + let(:comment_validation_message) { ResponseTemplate::COMMENT_VALIDATION_MSG } + it { is_expected.to validate_inclusion_of(:type_of).in_array(ResponseTemplate::TYPE_OF_TYPES) } it { is_expected.to validate_inclusion_of(:content_type).in_array(ResponseTemplate::CONTENT_TYPES) } @@ -9,7 +11,7 @@ RSpec.describe ResponseTemplate, type: :model do it "validates that the content type is body markdown" do response_template = build(:response_template, type_of: "personal_comment", content_type: "html") expect(response_template.valid?).to eq false - expect(response_template.errors.messages[:content_type].to_sentence).to eq ResponseTemplate::COMMENT_VALIDATION_MSG + expect(response_template.errors.messages[:content_type].to_sentence).to eq(comment_validation_message) end end @@ -17,13 +19,13 @@ RSpec.describe ResponseTemplate, type: :model do it "validates that the content type is body markdown" do response_template = build(:response_template, type_of: "mod_comment", content_type: "html") expect(response_template.valid?).to eq false - expect(response_template.errors.messages[:content_type].to_sentence).to eq ResponseTemplate::COMMENT_VALIDATION_MSG + expect(response_template.errors.messages[:content_type].to_sentence).to eq(comment_validation_message) end it "validates that there is no user ID associated" do response_template = build(:response_template, type_of: "mod_comment", content_type: "body_markdown", user_id: 1) expect(response_template.valid?).to eq false - expect(response_template.errors.messages[:type_of].to_sentence).to eq ResponseTemplate::USER_NIL_TYPE_OF_MSG + expect(response_template.errors.messages[:type_of].to_sentence).to eq(ResponseTemplate::USER_NIL_TYPE_OF_MSG) end end end diff --git a/spec/models/shared_examples/user_subscription_sourceable_spec.rb b/spec/models/shared_examples/user_subscription_sourceable_spec.rb index 6942f1fd4..7f62e534d 100644 --- a/spec/models/shared_examples/user_subscription_sourceable_spec.rb +++ b/spec/models/shared_examples/user_subscription_sourceable_spec.rb @@ -1,6 +1,8 @@ RSpec.shared_examples "UserSubscriptionSourceable" do let(:model) { described_class } - let(:source) { create(model.to_s.underscore.to_sym, :with_user_subscription_tag_role_user, with_user_subscription_tag: true) } + let(:source) do + create(model.to_s.underscore.to_sym, :with_user_subscription_tag_role_user, with_user_subscription_tag: true) + end let(:subscriber) { create(:user) } describe "#build_user_subscription" do @@ -22,7 +24,8 @@ RSpec.shared_examples "UserSubscriptionSourceable" do describe "#create_user_subscription" do it "returns a created UserSubcription with the correct attributes" do - user_subscription_fields = %w[author_id subsciber_id subscriber_email user_subscription_sourceable_id user_susbcription_sourceable_type] + user_subscription_fields = %w[author_id subsciber_id subscriber_email user_subscription_sourceable_id + user_susbcription_sourceable_type] user_subscription = create( :user_subscription, diff --git a/spec/models/tag_adjustment_spec.rb b/spec/models/tag_adjustment_spec.rb index 978c75abc..85d18d7b0 100644 --- a/spec/models/tag_adjustment_spec.rb +++ b/spec/models/tag_adjustment_spec.rb @@ -51,22 +51,26 @@ RSpec.describe TagAdjustment, type: :model do it "allows removal adjustment_types" do article = create(:article, tags: tag.name) - tag_adjustment = build(:tag_adjustment, user_id: mod_user.id, article_id: article.id, tag_id: tag.id, tag_name: tag.name, adjustment_type: "removal") + tag_adjustment = build(:tag_adjustment, user_id: mod_user.id, article_id: article.id, tag_id: tag.id, + tag_name: tag.name, adjustment_type: "removal") expect(tag_adjustment).to be_valid end it "disallows improper adjustment_types" do - tag_adjustment = build(:tag_adjustment, user_id: mod_user.id, article_id: article.id, tag_id: tag.id, adjustment_type: "slushie") + tag_adjustment = build(:tag_adjustment, user_id: mod_user.id, article_id: article.id, tag_id: tag.id, + adjustment_type: "slushie") expect(tag_adjustment).to be_invalid end it "allows proper status" do - tag_adjustment = build(:tag_adjustment, user_id: mod_user.id, article_id: article.id, tag_id: tag.id, status: "committed") + tag_adjustment = build(:tag_adjustment, user_id: mod_user.id, article_id: article.id, tag_id: tag.id, + status: "committed") expect(tag_adjustment).to be_valid end it "disallows improper status" do - tag_adjustment = build(:tag_adjustment, user_id: mod_user.id, article_id: article.id, tag_id: tag.id, status: "slushiemonkey") + tag_adjustment = build(:tag_adjustment, user_id: mod_user.id, article_id: article.id, tag_id: tag.id, + status: "slushiemonkey") expect(tag_adjustment).to be_invalid end end @@ -74,20 +78,26 @@ RSpec.describe TagAdjustment, type: :model do describe "validates article tag_list" do it "does not allow addition on articles with 4 tags" do article_tags_maxed = create(:article, tags: "ruby, javascript, html, css") - tag_adjustment = build(:tag_adjustment, user_id: admin_user.id, article_id: article_tags_maxed.id, tag_id: tag.id, tag_name: tag.name) + tag_adjustment = build(:tag_adjustment, user_id: admin_user.id, article_id: article_tags_maxed.id, + tag_id: tag.id, tag_name: tag.name) expect(tag_adjustment).to be_invalid end it "does not create if removed tag not on tag_list" do article = create(:article, tags: tag.name) - tag_adjustment = build(:tag_adjustment, user_id: admin_user.id, article_id: article.id, adjustment_type: "removal") + tag_adjustment = build(:tag_adjustment, user_id: admin_user.id, article_id: article.id, + adjustment_type: "removal") expect(tag_adjustment).to be_invalid end it "ignores case when checking tag_list" do news_tag = create(:tag, name: "news", pretty_name: "News") article = create(:article, tags: news_tag.name) - tag_adjustment = build(:tag_adjustment, user_id: admin_user.id, article_id: article.id, adjustment_type: "removal", tag_id: news_tag.id, tag_name: news_tag.pretty_name) + tag_adjustment = build( + :tag_adjustment, + user_id: admin_user.id, article_id: article.id, adjustment_type: "removal", + tag_id: news_tag.id, tag_name: news_tag.pretty_name + ) expect(tag_adjustment).to be_valid end end diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb index 78a524479..ddbda3092 100644 --- a/spec/models/tag_spec.rb +++ b/spec/models/tag_spec.rb @@ -116,7 +116,8 @@ RSpec.describe Tag, type: :model do it "on destroy enqueues job to delete tag from elasticsearch" do tag.save - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [described_class::SEARCH_CLASS.to_s, tag.id]) do + sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, + args: [described_class::SEARCH_CLASS.to_s, tag.id]) do tag.destroy end end diff --git a/spec/models/tweet_spec.rb b/spec/models/tweet_spec.rb index 32e385000..b0bcf35fb 100644 --- a/spec/models/tweet_spec.rb +++ b/spec/models/tweet_spec.rb @@ -91,7 +91,7 @@ RSpec.describe Tweet, type: :model, vcr: true do end end - context "when retrieving a non existent tweet", vcr: { cassette_name: "twitter_client_status_not_found_extended" } do + context "when retrieving non existent tweet", vcr: { cassette_name: "twitter_client_status_not_found_extended" } do it "raises an error if the tweet does not exist" do expect { described_class.find_or_fetch("0") }.to raise_error(TwitterClient::Errors::NotFound) end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index fe87ca8bb..37cb0a63c 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -135,7 +135,8 @@ RSpec.describe User, type: :model do it "has at most three optional fields" do expect(user_with_user_optional_fields).to have_many(:user_optional_fields).dependent(:destroy) - fourth_field = user_with_user_optional_fields.user_optional_fields.create(label: "some field", value: "some value") + fourth_field = user_with_user_optional_fields.user_optional_fields.create(label: "some field", + value: "some value") expect(fourth_field).not_to be_valid end @@ -241,7 +242,8 @@ RSpec.describe User, type: :model do it "on destroy enqueues job to delete user from elasticsearch" do user.save - sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, args: [described_class::SEARCH_CLASS.to_s, user.id]) do + sidekiq_assert_enqueued_with(job: Search::RemoveFromIndexWorker, + args: [described_class::SEARCH_CLASS.to_s, user.id]) do user.destroy end end @@ -972,7 +974,8 @@ RSpec.describe User, type: :model do describe "theming properties" do it "creates proper body class with defaults" do - expect(user.decorate.config_body_class).to eq("default default-article-body trusted-status-#{user.trusted} #{user.config_navbar}-navbar-config") + classes = "default default-article-body trusted-status-#{user.trusted} #{user.config_navbar}-navbar-config" + expect(user.decorate.config_body_class).to eq(classes) end it "determines dark theme if night theme" do @@ -992,22 +995,30 @@ RSpec.describe User, type: :model do it "creates proper body class with sans serif config" do user.config_font = "sans_serif" - expect(user.decorate.config_body_class).to eq("default sans-serif-article-body trusted-status-#{user.trusted} #{user.config_navbar}-navbar-config") + + classes = "default sans-serif-article-body trusted-status-#{user.trusted} #{user.config_navbar}-navbar-config" + expect(user.decorate.config_body_class).to eq(classes) end it "creates proper body class with open dyslexic config" do user.config_font = "open_dyslexic" - expect(user.decorate.config_body_class).to eq("default open-dyslexic-article-body trusted-status-#{user.trusted} #{user.config_navbar}-navbar-config") + + classes = "default open-dyslexic-article-body trusted-status-#{user.trusted} #{user.config_navbar}-navbar-config" + expect(user.decorate.config_body_class).to eq(classes) end it "creates proper body class with night theme" do user.config_theme = "night_theme" - expect(user.decorate.config_body_class).to eq("night-theme default-article-body trusted-status-#{user.trusted} #{user.config_navbar}-navbar-config") + + classes = "night-theme default-article-body trusted-status-#{user.trusted} #{user.config_navbar}-navbar-config" + expect(user.decorate.config_body_class).to eq(classes) end it "creates proper body class with pink theme" do user.config_theme = "pink_theme" - expect(user.decorate.config_body_class).to eq("pink-theme default-article-body trusted-status-#{user.trusted} #{user.config_navbar}-navbar-config") + + classes = "pink-theme default-article-body trusted-status-#{user.trusted} #{user.config_navbar}-navbar-config" + expect(user.decorate.config_body_class).to eq(classes) end end diff --git a/spec/models/user_subscription_spec.rb b/spec/models/user_subscription_spec.rb index f19da930c..c6a57ec14 100644 --- a/spec/models/user_subscription_spec.rb +++ b/spec/models/user_subscription_spec.rb @@ -13,10 +13,17 @@ RSpec.describe UserSubscription, type: :model do it { is_expected.to validate_presence_of(:subscriber_email) } it { is_expected.to validate_presence_of(:author_id) } it { is_expected.to validate_inclusion_of(:user_subscription_sourceable_type).in_array(%w[Article]) } - it { is_expected.to validate_uniqueness_of(:subscriber_id).scoped_to(%i[subscriber_email user_subscription_sourceable_type user_subscription_sourceable_id]) } + + # rubocop:disable RSpec/NamedSubject + it { + expect(subject).to validate_uniqueness_of(:subscriber_id). + scoped_to(%i[subscriber_email user_subscription_sourceable_type user_subscription_sourceable_id]) + } + # rubocop:enable RSpec/NamedSubject it "validates the source is active" do - unpublished_source = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true, published: false) + unpublished_source = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true, + published: false) user_subscription = described_class.build(source: unpublished_source, subscriber: subscriber) expect(user_subscription).not_to be_valid expect(user_subscription.errors[:base]).to include "Source not found." @@ -33,7 +40,9 @@ RSpec.describe UserSubscription, type: :model do subscriber_with_apple_relay = create(:user, email: "test@privaterelay.appleid.com") user_subscription = described_class.build(source: source, subscriber: subscriber_with_apple_relay) expect(user_subscription).not_to be_valid - expect(user_subscription.errors[:subscriber_email]).to include "Can't subscribe with an Apple private relay. Please update email." + + error = "Can't subscribe with an Apple private relay. Please update email." + expect(user_subscription.errors[:subscriber_email]).to include(error) end end diff --git a/spec/policies/chat_channel_membership_policy_spec.rb b/spec/policies/chat_channel_membership_policy_spec.rb index 341f92873..b1981127e 100644 --- a/spec/policies/chat_channel_membership_policy_spec.rb +++ b/spec/policies/chat_channel_membership_policy_spec.rb @@ -21,7 +21,9 @@ RSpec.describe ChatChannelMembershipPolicy, type: :policy do context "when user does not belong to membership" do let(:other_user) { build_stubbed(:user) } - let(:chat_channel_membership) { build_stubbed(:chat_channel_membership, user: other_user, chat_channel: chat_channel) } + let(:chat_channel_membership) do + build_stubbed(:chat_channel_membership, user: other_user, chat_channel: chat_channel) + end it { is_expected.to forbid_actions(%i[update destroy]) } end diff --git a/spec/policies/comment_policy_spec.rb b/spec/policies/comment_policy_spec.rb index 61d5bfeb2..2c5cb6653 100644 --- a/spec/policies/comment_policy_spec.rb +++ b/spec/policies/comment_policy_spec.rb @@ -53,7 +53,8 @@ RSpec.describe CommentPolicy, type: :policy do it { is_expected.to permit_actions(%i[create moderator_create]) } it do - expect(comment_policy).to permit_mass_assignment_of(valid_attributes_for_moderator_create).for_action(:moderator_create) + expect(comment_policy).to permit_mass_assignment_of(valid_attributes_for_moderator_create). + for_action(:moderator_create) end end @@ -63,7 +64,8 @@ RSpec.describe CommentPolicy, type: :policy do it { is_expected.to permit_actions(%i[create moderator_create]) } it do - expect(comment_policy).to permit_mass_assignment_of(valid_attributes_for_moderator_create).for_action(:moderator_create) + expect(comment_policy).to permit_mass_assignment_of(valid_attributes_for_moderator_create). + for_action(:moderator_create) end end end @@ -109,7 +111,8 @@ RSpec.describe CommentPolicy, type: :policy do it do expect(comment_policy).to permit_mass_assignment_of(valid_attributes_for_update).for_action(:update) - expect(comment_policy).to permit_mass_assignment_of(valid_attributes_for_moderator_create).for_action(:moderator_create) + expect(comment_policy).to permit_mass_assignment_of(valid_attributes_for_moderator_create). + for_action(:moderator_create) end end end diff --git a/spec/requests/api/v0/articles_spec.rb b/spec/requests/api/v0/articles_spec.rb index 31218626f..e76b10f27 100644 --- a/spec/requests/api/v0/articles_spec.rb +++ b/spec/requests/api/v0/articles_spec.rb @@ -546,7 +546,8 @@ RSpec.describe "Api::V0::Articles", type: :request do access_token = create(:doorkeeper_access_token, resource_owner_id: user.id, scopes: "write_articles") headers = { "authorization" => "Bearer #{access_token.token}", "content-type" => "application/json" } - post api_articles_path, params: { article: { title: Faker::Book.title, body_markdown: "" } }.to_json, headers: headers + post api_articles_path, params: { article: { title: Faker::Book.title, + body_markdown: "" } }.to_json, headers: headers expect(response).to have_http_status(:created) end diff --git a/spec/requests/api/v0/webhooks_spec.rb b/spec/requests/api/v0/webhooks_spec.rb index 1d3ff9641..8cd45fc28 100644 --- a/spec/requests/api/v0/webhooks_spec.rb +++ b/spec/requests/api/v0/webhooks_spec.rb @@ -27,7 +27,8 @@ RSpec.describe "Api::V0::Webhooks", type: :request do it "returns a 200 if authorized" do access_token = create(:doorkeeper_access_token, resource_owner_id: user.id, scopes: "public") - webhook = create(:webhook_endpoint, user: user, target_url: "https://api.example.com/go2", oauth_application_id: access_token.application_id) + webhook = create(:webhook_endpoint, user: user, target_url: "https://api.example.com/go2", + oauth_application_id: access_token.application_id) headers = { "authorization" => "Bearer #{access_token.token}", "content-type" => "application/json" } get api_webhooks_path, headers: headers expect(response).to have_http_status(:ok) @@ -201,7 +202,9 @@ RSpec.describe "Api::V0::Webhooks", type: :request do describe "authorized with doorkeeper" do let!(:oauth_app) { create(:application) } let!(:oauth_app2) { create(:application) } - let(:access_token) { create :doorkeeper_access_token, resource_owner: user, application: oauth_app2, scopes: "public" } + let(:access_token) do + create :doorkeeper_access_token, resource_owner: user, application: oauth_app2, scopes: "public" + end it "renders index successfully" do get api_webhooks_path, params: { access_token: access_token.token } diff --git a/spec/requests/article_approvals_spec.rb b/spec/requests/article_approvals_spec.rb index 651a2c4b3..8510ebc77 100644 --- a/spec/requests/article_approvals_spec.rb +++ b/spec/requests/article_approvals_spec.rb @@ -12,7 +12,9 @@ RSpec.describe "ArticleApprovals", type: :request do end it "does not allow update" do - expect { post "/article_approvals", params: { approved: true, id: article.id } }.to raise_error(Pundit::NotAuthorizedError) + expect do + post "/article_approvals", params: { approved: true, id: article.id } + end.to raise_error(Pundit::NotAuthorizedError) end end @@ -39,12 +41,16 @@ RSpec.describe "ArticleApprovals", type: :request do second_tag = create(:tag, requires_approval: false) third_tag = create(:tag, requires_approval: false) article = create(:article, tags: [third_tag.name, second_tag.name]) - expect { post "/article_approvals", params: { approved: true, id: article.id } }.to raise_error(Pundit::NotAuthorizedError) + expect do + post "/article_approvals", params: { approved: true, id: article.id } + end.to raise_error(Pundit::NotAuthorizedError) end it "does not allow update with one tag and does not require approval" do tag.update_column(:requires_approval, false) - expect { post "/article_approvals", params: { approved: true, id: article.id } }.to raise_error(Pundit::NotAuthorizedError) + expect do + post "/article_approvals", params: { approved: true, id: article.id } + end.to raise_error(Pundit::NotAuthorizedError) end end diff --git a/spec/requests/articles/articles_create_spec.rb b/spec/requests/articles/articles_create_spec.rb index aaaa6f4cb..a30323222 100644 --- a/spec/requests/articles/articles_create_spec.rb +++ b/spec/requests/articles/articles_create_spec.rb @@ -88,7 +88,8 @@ RSpec.describe "ArticlesCreate", type: :request do end it "schedules a dispatching event job (published)" do - article_params[:article][:body_markdown] = "---\ntitle: hey hey hahuu\npublished: true\nseries: helloyo\n---\nYo ho ho#{rand(100)}" + body_markdown = "---\ntitle: hey hey hahuu\npublished: true\nseries: helloyo\n---\nYo ho ho#{rand(100)}" + article_params[:article][:body_markdown] = body_markdown sidekiq_assert_enqueued_jobs(1, only: Webhook::DispatchEventWorker) do post "/articles", params: article_params end diff --git a/spec/requests/chat_channels_spec.rb b/spec/requests/chat_channels_spec.rb index 7599827b9..78dc39734 100644 --- a/spec/requests/chat_channels_spec.rb +++ b/spec/requests/chat_channels_spec.rb @@ -53,7 +53,8 @@ RSpec.describe "ChatChannels", type: :request do describe "get /chat_channels?state=joining_request" do it "returns joining request channels" do - membership = ChatChannelMembership.create(chat_channel_id: invite_channel.id, user_id: user.id, status: "joining_request", role: "mod") + membership = ChatChannelMembership.create(chat_channel_id: invite_channel.id, user_id: user.id, + status: "joining_request", role: "mod") membership.chat_channel.update(discoverable: true) sign_in user get "/chat_channels?state=joining_request" diff --git a/spec/requests/internal/configs_spec.rb b/spec/requests/internal/configs_spec.rb index ee13bf415..a8bac87e6 100644 --- a/spec/requests/internal/configs_spec.rb +++ b/spec/requests/internal/configs_spec.rb @@ -4,7 +4,9 @@ RSpec.describe "/internal/config", type: :request do let_it_be(:user) { create(:user) } let_it_be(:admin) { create(:user, :super_admin) } let_it_be(:admin_plus_config) { create(:user, :super_plus_single_resource_admin, resource: Config) } - let_it_be(:confirmation_message) { "My username is @#{admin_plus_config.username} and this action is 100% safe and appropriate." } + let_it_be(:confirmation_message) do + "My username is @#{admin_plus_config.username} and this action is 100% safe and appropriate." + end describe "POST internal/events as a user" do before do @@ -25,12 +27,18 @@ RSpec.describe "/internal/config", type: :request do it "does not allow user to update config if they have proper confirmation" do expected_image_url = "https://dummyimage.com/300x300" - expect { post "/internal/config", params: { site_config: { favicon_url: expected_image_url }, confirmation: confirmation_message } }.to raise_error Pundit::NotAuthorizedError + expect do + post "/internal/config", params: { site_config: { favicon_url: expected_image_url }, + confirmation: confirmation_message } + end.to raise_error Pundit::NotAuthorizedError end it "does not allow user to update config if they do not have proper confirmation" do expected_image_url = "https://dummyimage.com/300x300" - expect { post "/internal/config", params: { site_config: { favicon_url: expected_image_url }, confirmation: "Not proper" } }.to raise_error Pundit::NotAuthorizedError + expect do + post "/internal/config", params: { site_config: { favicon_url: expected_image_url }, + confirmation: "Not proper" } + end.to raise_error Pundit::NotAuthorizedError end end @@ -42,7 +50,8 @@ RSpec.describe "/internal/config", type: :request do describe "API tokens" do it "updates the health_check_token" do token = rand(20).to_s - post "/internal/config", params: { site_config: { health_check_token: token }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { health_check_token: token }, + confirmation: confirmation_message } expect(SiteConfig.health_check_token).to eq token end end @@ -50,14 +59,16 @@ RSpec.describe "/internal/config", type: :request do describe "Authentication" do it "updates enabled authentication providers" do enabled = Array.wrap(Authentication::Providers.available.first.to_s) - post "/internal/config", params: { site_config: { authentication_providers: enabled }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { authentication_providers: enabled }, + confirmation: confirmation_message } expect(SiteConfig.authentication_providers).to eq(enabled) end it "strips empty elements" do provider = Authentication::Providers.available.first.to_s enabled = [provider, "", nil] - post "/internal/config", params: { site_config: { authentication_providers: enabled }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { authentication_providers: enabled }, + confirmation: confirmation_message } expect(SiteConfig.authentication_providers).to eq([provider]) end end @@ -66,19 +77,22 @@ RSpec.describe "/internal/config", type: :request do it "updates the community_description" do allow(SiteConfig).to receive(:community_description).and_call_original description = "Hey hey #{rand(100)}" - post "/internal/config", params: { site_config: { community_description: description }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { community_description: description }, + confirmation: confirmation_message } expect(SiteConfig.community_description).to eq(description) end it "updates the community_member_label" do name = "developer" - post "/internal/config", params: { site_config: { community_member_label: name }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { community_member_label: name }, + confirmation: confirmation_message } expect(SiteConfig.community_member_label).to eq(name) end it "updates the community_action" do action = "reading" - post "/internal/config", params: { site_config: { community_member_label: action }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { community_member_label: action }, + confirmation: confirmation_message } expect(SiteConfig.community_member_label).to eq(action) end @@ -107,29 +121,36 @@ RSpec.describe "/internal/config", type: :request do describe "Email digest frequency" do it "updates periodic_email_digest_max" do - post "/internal/config", params: { site_config: { periodic_email_digest_max: 1 }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { periodic_email_digest_max: 1 }, + confirmation: confirmation_message } expect(SiteConfig.periodic_email_digest_max).to eq(1) end it "updates periodic_email_digest_min" do - post "/internal/config", params: { site_config: { periodic_email_digest_min: 3 }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { periodic_email_digest_min: 3 }, + confirmation: confirmation_message } expect(SiteConfig.periodic_email_digest_min).to eq(3) end it "rejects update without proper confirmation" do - expect { post "/internal/config", params: { site_config: { periodic_email_digest_min: 6 }, confirmation: "Incorrect yo!" } }.to raise_error Pundit::NotAuthorizedError + expect do + post "/internal/config", params: { site_config: { periodic_email_digest_min: 6 }, + confirmation: "Incorrect yo!" } + end.to raise_error Pundit::NotAuthorizedError expect(SiteConfig.periodic_email_digest_min).not_to eq(6) end end describe "Jobs" do it "updates jobs_url" do - post "/internal/config", params: { site_config: { jobs_url: "www.jobs.com" }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { jobs_url: "www.jobs.com" }, + confirmation: confirmation_message } expect(SiteConfig.jobs_url).to eq("www.jobs.com") end it "updates display_jobs_banner" do - post "/internal/config", params: { site_config: { display_jobs_banner: true }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { display_jobs_banner: true }, + confirmation: confirmation_message } expect(SiteConfig.display_jobs_banner).to eq(true) end end @@ -149,62 +170,74 @@ RSpec.describe "/internal/config", type: :request do describe "Images" do it "updates main_social_image" do expected_image_url = "https://dummyimage.com/300x300" - post "/internal/config", params: { site_config: { main_social_image: expected_image_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { main_social_image: expected_image_url }, + confirmation: confirmation_message } expect(SiteConfig.main_social_image).to eq(expected_image_url) end it "updates favicon_url" do expected_image_url = "https://dummyimage.com/300x300" - post "/internal/config", params: { site_config: { favicon_url: expected_image_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { favicon_url: expected_image_url }, + confirmation: confirmation_message } expect(SiteConfig.favicon_url).to eq(expected_image_url) end it "updates logo_png" do expected_image_url = "https://dummyimage.com/300x300" - post "/internal/config", params: { site_config: { logo_png: expected_image_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { logo_png: expected_image_url }, + confirmation: confirmation_message } expect(SiteConfig.logo_png).to eq(expected_image_url) end it "updates logo_svg" do expected_image_url = "https://dummyimage.com/300x300" - post "/internal/config", params: { site_config: { logo_svg: expected_image_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { logo_svg: expected_image_url }, + confirmation: confirmation_message } expect(SiteConfig.logo_svg).to eq(expected_image_url) end it "updates secondary_logo_url" do expected_image_url = "https://dummyimage.com/300x300" - post "/internal/config", params: { site_config: { secondary_logo_url: expected_image_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { secondary_logo_url: expected_image_url }, + confirmation: confirmation_message } expect(SiteConfig.secondary_logo_url).to eq(expected_image_url) end it "rejects update without proper confirmation" do expected_image_url = "https://dummyimage.com/300x300" - expect { post "/internal/config", params: { site_config: { logo_svg: expected_image_url }, confirmation: "Incorrect yo!" } }.to raise_error Pundit::NotAuthorizedError + expect do + post "/internal/config", params: { site_config: { logo_svg: expected_image_url }, + confirmation: "Incorrect yo!" } + end.to raise_error Pundit::NotAuthorizedError end end describe "Mascot" do it "updates the mascot_user_id" do expected_mascot_user_id = 2 - post "/internal/config", params: { site_config: { mascot_user_id: expected_mascot_user_id }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { mascot_user_id: expected_mascot_user_id }, + confirmation: confirmation_message } expect(SiteConfig.mascot_user_id).to eq(expected_mascot_user_id) end it "updates mascot_image_url" do expected_image_url = "https://dummyimage.com/300x300" - post "/internal/config", params: { site_config: { mascot_image_url: expected_image_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { mascot_image_url: expected_image_url }, + confirmation: confirmation_message } expect(SiteConfig.mascot_image_url).to eq(expected_image_url) end it "updates mascot_footer_image_url" do expected_image_url = "https://dummyimage.com/300x300" - post "/internal/config", params: { site_config: { mascot_footer_image_url: expected_image_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { mascot_footer_image_url: expected_image_url }, + confirmation: confirmation_message } expect(SiteConfig.mascot_footer_image_url).to eq(expected_image_url) end it "updates mascot_image_description" do description = "Hey hey #{rand(100)}" - post "/internal/config", params: { site_config: { mascot_image_description: description }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { mascot_image_description: description }, + confirmation: confirmation_message } expect(SiteConfig.mascot_image_description).to eq(description) end end @@ -222,7 +255,8 @@ RSpec.describe "/internal/config", type: :request do describe "Monetization" do it "updates payment pointer" do - post "/internal/config", params: { site_config: { payment_pointer: "$pay.yo" }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { payment_pointer: "$pay.yo" }, + confirmation: confirmation_message } expect(SiteConfig.payment_pointer).to eq("$pay.yo") end @@ -249,7 +283,8 @@ RSpec.describe "/internal/config", type: :request do it "updates shop url" do expected_shop_url = "https://qshop.dev.to" - post "/internal/config", params: { site_config: { shop_url: expected_shop_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { shop_url: expected_shop_url }, + confirmation: confirmation_message } expect(SiteConfig.shop_url).to eq(expected_shop_url) get "/privacy" expect(response.body).to include(expected_shop_url) @@ -260,22 +295,26 @@ RSpec.describe "/internal/config", type: :request do describe "Newsletter" do it "updates mailchimp_newsletter_id" do - post "/internal/config", params: { site_config: { mailchimp_newsletter_id: "abc" }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { mailchimp_newsletter_id: "abc" }, + confirmation: confirmation_message } expect(SiteConfig.mailchimp_newsletter_id).to eq("abc") end it "updates mailchimp_sustaining_members_id" do - post "/internal/config", params: { site_config: { mailchimp_sustaining_members_id: "abc" }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { mailchimp_sustaining_members_id: "abc" }, + confirmation: confirmation_message } expect(SiteConfig.mailchimp_sustaining_members_id).to eq("abc") end it "updates mailchimp_tag_moderators_id" do - post "/internal/config", params: { site_config: { mailchimp_tag_moderators_id: "abc" }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { mailchimp_tag_moderators_id: "abc" }, + confirmation: confirmation_message } expect(SiteConfig.mailchimp_tag_moderators_id).to eq("abc") end it "updates mailchimp_community_moderators_id" do - post "/internal/config", params: { site_config: { mailchimp_community_moderators_id: "abc" }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { mailchimp_community_moderators_id: "abc" }, + confirmation: confirmation_message } expect(SiteConfig.mailchimp_community_moderators_id).to eq("abc") end end @@ -283,39 +322,50 @@ RSpec.describe "/internal/config", type: :request do describe "Onboarding" do it "updates onboarding_taskcard_image" do expected_image_url = "https://dummyimage.com/300x300" - post "/internal/config", params: { site_config: { onboarding_taskcard_image: expected_image_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { onboarding_taskcard_image: expected_image_url }, + confirmation: confirmation_message } expect(SiteConfig.onboarding_taskcard_image).to eq(expected_image_url) end it "updates onboarding_logo_image" do expected_image_url = "https://dummyimage.com/300x300" - post "/internal/config", params: { site_config: { onboarding_logo_image: expected_image_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { onboarding_logo_image: expected_image_url }, + confirmation: confirmation_message } expect(SiteConfig.onboarding_logo_image).to eq(expected_image_url) end it "updates onboarding_background_image" do expected_image_url = "https://dummyimage.com/300x300" - post "/internal/config", params: { site_config: { onboarding_background_image: expected_image_url }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { onboarding_background_image: expected_image_url }, + confirmation: confirmation_message } expect(SiteConfig.onboarding_background_image).to eq(expected_image_url) end it "removes space suggested_tags" do - post "/internal/config", params: { site_config: { suggested_tags: "hey, haha,hoho, bobo fofo" }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { suggested_tags: "hey, haha,hoho, bobo fofo" }, + confirmation: confirmation_message } expect(SiteConfig.suggested_tags).to eq(%w[hey haha hoho bobofofo]) end it "downcases suggested_tags" do - post "/internal/config", params: { site_config: { suggested_tags: "hey, haha,hoHo, Bobo Fofo" }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { suggested_tags: "hey, haha,hoHo, Bobo Fofo" }, + confirmation: confirmation_message } expect(SiteConfig.suggested_tags).to eq(%w[hey haha hoho bobofofo]) end it "removes space suggested_users" do - post "/internal/config", params: { site_config: { suggested_users: "piglet, tigger,eeyore, Christopher Robin, kanga,roo" }, confirmation: confirmation_message } + post "/internal/config", params: { + site_config: { suggested_users: "piglet, tigger,eeyore, Christopher Robin, kanga,roo" }, + confirmation: confirmation_message + } expect(SiteConfig.suggested_users).to eq(%w[piglet tigger eeyore christopherrobin kanga roo]) end it "downcases suggested_users" do - post "/internal/config", params: { site_config: { suggested_users: "piglet, tigger,EEYORE, Christopher Robin, KANGA,RoO" }, confirmation: confirmation_message } + post "/internal/config", params: { + site_config: { suggested_users: "piglet, tigger,EEYORE, Christopher Robin, KANGA,RoO" }, + confirmation: confirmation_message + } expect(SiteConfig.suggested_users).to eq(%w[piglet tigger eeyore christopherrobin kanga roo]) end end @@ -323,43 +373,50 @@ RSpec.describe "/internal/config", type: :request do describe "Rate Limits" do it "updates rate_limit_follow_count_daily" do expect do - post "/internal/config", params: { site_config: { rate_limit_follow_count_daily: 3 }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { rate_limit_follow_count_daily: 3 }, + confirmation: confirmation_message } end.to change(SiteConfig, :rate_limit_follow_count_daily).from(500).to(3) end it "updates rate_limit_comment_creation" do expect do - post "/internal/config", params: { site_config: { rate_limit_comment_creation: 3 }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { rate_limit_comment_creation: 3 }, + confirmation: confirmation_message } end.to change(SiteConfig, :rate_limit_comment_creation).from(9).to(3) end it "updates rate_limit_published_article_creation" do expect do - post "/internal/config", params: { site_config: { rate_limit_published_article_creation: 3 }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { rate_limit_published_article_creation: 3 }, + confirmation: confirmation_message } end.to change(SiteConfig, :rate_limit_published_article_creation).from(9).to(3) end it "updates rate_limit_organization_creation" do expect do - post "/internal/config", params: { site_config: { rate_limit_organization_creation: 3 }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { rate_limit_organization_creation: 3 }, + confirmation: confirmation_message } end.to change(SiteConfig, :rate_limit_organization_creation).from(1).to(3) end it "updates rate_limit_image_upload" do expect do - post "/internal/config", params: { site_config: { rate_limit_image_upload: 3 }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { rate_limit_image_upload: 3 }, + confirmation: confirmation_message } end.to change(SiteConfig, :rate_limit_image_upload).from(9).to(3) end it "updates rate_limit_email_recipient" do expect do - post "/internal/config", params: { site_config: { rate_limit_email_recipient: 3 }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { rate_limit_email_recipient: 3 }, + confirmation: confirmation_message } end.to change(SiteConfig, :rate_limit_email_recipient).from(5).to(3) end it "updates rate_limit_user_subscription_creation" do expect do - post "/internal/config", params: { site_config: { rate_limit_user_subscription_creation: 1 }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { rate_limit_user_subscription_creation: 1 }, + confirmation: confirmation_message } end.to change(SiteConfig, :rate_limit_user_subscription_creation).from(3).to(1) end end @@ -397,12 +454,14 @@ RSpec.describe "/internal/config", type: :request do describe "Tags" do it "removes space sidebar_tags" do - post "/internal/config", params: { site_config: { sidebar_tags: "hey, haha,hoho, bobo fofo" }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { sidebar_tags: "hey, haha,hoho, bobo fofo" }, + confirmation: confirmation_message } expect(SiteConfig.sidebar_tags).to eq(%w[hey haha hoho bobofofo]) end it "downcases sidebar_tags" do - post "/internal/config", params: { site_config: { sidebar_tags: "hey, haha,hoHo, Bobo Fofo" }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { sidebar_tags: "hey, haha,hoHo, Bobo Fofo" }, + confirmation: confirmation_message } expect(SiteConfig.sidebar_tags).to eq(%w[hey haha hoho bobofofo]) end end @@ -410,7 +469,8 @@ RSpec.describe "/internal/config", type: :request do describe "User Experience" do it "updates the feed_style" do feed_style = "basic" - post "/internal/config", params: { site_config: { mascot_user_id: feed_style }, confirmation: confirmation_message } + post "/internal/config", params: { site_config: { mascot_user_id: feed_style }, + confirmation: confirmation_message } expect(SiteConfig.feed_style).to eq(feed_style) end end diff --git a/spec/requests/internal/podcasts_spec.rb b/spec/requests/internal/podcasts_spec.rb index cacf8cccb..63b1d36ac 100644 --- a/spec/requests/internal/podcasts_spec.rb +++ b/spec/requests/internal/podcasts_spec.rb @@ -61,14 +61,16 @@ RSpec.describe "/internal/podcasts", type: :request do describe "Updating" do it "updates" do - put internal_podcast_path(podcast), params: { podcast: { title: "hello", feed_url: "https://pod.example.com/rss.rss" } } + put internal_podcast_path(podcast), params: { podcast: { title: "hello", + feed_url: "https://pod.example.com/rss.rss" } } podcast.reload expect(podcast.title).to eq("hello") expect(podcast.feed_url).to eq("https://pod.example.com/rss.rss") end it "redirects after update" do - put internal_podcast_path(podcast), params: { podcast: { title: "hello", feed_url: "https://pod.example.com/rss.rss" } } + put internal_podcast_path(podcast), params: { podcast: { title: "hello", + feed_url: "https://pod.example.com/rss.rss" } } expect(response).to redirect_to(internal_podcasts_path) end end @@ -81,13 +83,15 @@ RSpec.describe "/internal/podcasts", type: :request do end it "schedules a worker to fetch episodes" do - sidekiq_assert_enqueued_with(job: Podcasts::GetEpisodesWorker, args: [{ podcast_id: podcast.id, limit: 5, force: false }]) do + sidekiq_assert_enqueued_with(job: Podcasts::GetEpisodesWorker, + args: [{ podcast_id: podcast.id, limit: 5, force: false }]) do post fetch_internal_podcast_path(podcast.id), params: { limit: "5", force: nil } end end it "schedules a worker without limit and with force" do - sidekiq_assert_enqueued_with(job: Podcasts::GetEpisodesWorker, args: [{ podcast_id: podcast.id, force: true, limit: nil }]) do + sidekiq_assert_enqueued_with(job: Podcasts::GetEpisodesWorker, + args: [{ podcast_id: podcast.id, force: true, limit: nil }]) do post fetch_internal_podcast_path(podcast.id), params: { force: "1", limit: "" } end end diff --git a/spec/requests/internal/sponsorships_spec.rb b/spec/requests/internal/sponsorships_spec.rb index 6be76f9f6..13319a9fb 100644 --- a/spec/requests/internal/sponsorships_spec.rb +++ b/spec/requests/internal/sponsorships_spec.rb @@ -24,7 +24,10 @@ RSpec.describe "/internal/sponsorships", type: :request do describe "GET /internal/sponsorships/:id/edit" do let(:ruby) { build_stubbed(:tag, name: "ruby") } - let!(:sponsorship) { create(:sponsorship, organization: org, level: :tag, sponsorable: ruby, status: "pending", expires_at: Time.current) } + let!(:sponsorship) do + create(:sponsorship, organization: org, level: :tag, sponsorable: ruby, status: "pending", + expires_at: Time.current) + end before do sign_in admin @@ -38,7 +41,10 @@ RSpec.describe "/internal/sponsorships", type: :request do describe "PUT /internal/sponsorships/:id" do let(:ruby) { build_stubbed(:tag, name: "ruby") } - let!(:sponsorship) { create(:sponsorship, organization: org, level: :tag, sponsorable: ruby, status: "pending", expires_at: Time.current) } + let!(:sponsorship) do + create(:sponsorship, organization: org, level: :tag, sponsorable: ruby, status: "pending", + expires_at: Time.current) + end let(:valid_attributes) { { status: "live", expires_at: 1.month.from_now, blurb_html: Faker::Book.title } } let(:invalid_attributes) { { status: "super-live", expires_at: 1.month.from_now } } @@ -72,7 +78,9 @@ RSpec.describe "/internal/sponsorships", type: :request do end describe "DELETE /internal/sponsorships/:id" do - let!(:sponsorship) { create(:sponsorship, organization: org, level: :silver, status: "live", expires_at: Time.current) } + let!(:sponsorship) do + create(:sponsorship, organization: org, level: :silver, status: "live", expires_at: Time.current) + end it "destroys a sponsorship" do sign_in admin diff --git a/spec/requests/internal/users_manage_spec.rb b/spec/requests/internal/users_manage_spec.rb index b6cee5337..889f80c22 100644 --- a/spec/requests/internal/users_manage_spec.rb +++ b/spec/requests/internal/users_manage_spec.rb @@ -23,7 +23,8 @@ RSpec.describe "Internal::Users", type: :request do # create user3 reaction to user2 comment create(:reaction, reactable: comment, reactable_type: "Comment", user: user3) # create user3 comment response to user2 comment - comment2 = create(:comment, commentable_type: "Article", commentable: article, user: user3, ancestry: comment.id, body_markdown: "Hello @#{user2.username}, you are cool.") + comment2 = create(:comment, commentable_type: "Article", commentable: article, user: user3, ancestry: comment.id, + body_markdown: "Hello @#{user2.username}, you are cool.") # create user2 reaction to user3 comment response create(:reaction, reactable: comment2, reactable_type: "Comment", user: user2) # create user3 reaction to offending article @@ -118,7 +119,9 @@ RSpec.describe "Internal::Users", type: :request do context "when managing activity and roles" do it "adds comment ban role" do - patch "/internal/users/#{user.id}/user_status", params: { user: { user_status: "Comment Ban", note_for_current_role: "comment ban this user" } } + params = { user: { user_status: "Comment Ban", note_for_current_role: "comment ban this user" } } + patch "/internal/users/#{user.id}/user_status", params: params + expect(user.roles.first.name).to eq("comment_banned") expect(Note.first.content).to eq("comment ban this user") end @@ -126,7 +129,10 @@ RSpec.describe "Internal::Users", type: :request do it "selects new role for user" do user.add_role :trusted user.reload - patch "/internal/users/#{user.id}/user_status", params: { user: { user_status: "Comment Ban", note_for_current_role: "comment ban this user" } } + + params = { user: { user_status: "Comment Ban", note_for_current_role: "comment ban this user" } } + patch "/internal/users/#{user.id}/user_status", params: params + expect(user.roles.count).to eq(1) expect(user.roles.last.name).to eq("comment_banned") end diff --git a/spec/requests/internal/users_spec.rb b/spec/requests/internal/users_spec.rb index fbcaf4bf8..882e7f3e0 100644 --- a/spec/requests/internal/users_spec.rb +++ b/spec/requests/internal/users_spec.rb @@ -61,9 +61,10 @@ RSpec.describe "internal/users", type: :request do ) verification_link = app_url(path) - expect(ActionMailer::Base.deliveries.count).to eq(1) - expect(ActionMailer::Base.deliveries.first.subject).to eq("Verify Your #{ApplicationConfig['COMMUNITY_NAME']} Account Ownership") - expect(ActionMailer::Base.deliveries.first.text_part.body).to include(verification_link) + deliveries = ActionMailer::Base.deliveries + expect(deliveries.count).to eq(1) + expect(deliveries.first.subject).to eq("Verify Your #{ApplicationConfig['COMMUNITY_NAME']} Account Ownership") + expect(deliveries.first.text_part.body).to include(verification_link) sign_in(user) get verification_link diff --git a/spec/requests/moderations_spec.rb b/spec/requests/moderations_spec.rb index 5a6734a3e..a86dcbf36 100644 --- a/spec/requests/moderations_spec.rb +++ b/spec/requests/moderations_spec.rb @@ -76,7 +76,9 @@ RSpec.describe "Moderations", type: :request do end it "renders not_found when an article can't be found" do - expect { get "/#{trusted_user.username}/dsdsdsweweedsdseweww/mod/" }.to raise_exception(ActiveRecord::RecordNotFound) + expect do + get "/#{trusted_user.username}/dsdsdsweweedsdseweww/mod/" + end.to raise_exception(ActiveRecord::RecordNotFound) end end diff --git a/spec/requests/notification_subscriptions_spec.rb b/spec/requests/notification_subscriptions_spec.rb index feb8a5f4f..afc8dafc3 100644 --- a/spec/requests/notification_subscriptions_spec.rb +++ b/spec/requests/notification_subscriptions_spec.rb @@ -8,12 +8,31 @@ RSpec.describe "NotificationSubscriptions", type: :request do let(:headers) { { Accept: "application/json" } } let(:comment) { create(:comment, commentable: article, user: user) } let(:parent_comment_by_og) { create(:comment, commentable: article, user: user) } - let(:child_of_parent_by_other) { create(:comment, commentable: article, user: other_user, ancestry: parent_comment_by_og.id.to_s) } - let(:child_of_child_by_og) { create(:comment, commentable: article, user: user, ancestry: "#{parent_comment_by_og.id}/#{child_of_parent_by_other.id}") } - let(:child_of_child_of_child_by_other) { create(:comment, commentable: article, user: other_user, ancestry: "#{parent_comment_by_og.id}/#{child_of_parent_by_other.id}/#{child_of_child_by_og.id}") } - let(:child_of_child_of_child_by_og) { create(:comment, commentable: article, user: user, ancestry: "#{parent_comment_by_og.id}/#{child_of_parent_by_other.id}/#{child_of_child_by_og.id}/#{child_of_child_by_other.id}") } - let(:child_of_child_by_other) { create(:comment, commentable: article, user: other_user, ancestry: "#{parent_comment_by_og.id}/#{child_of_parent_by_other.id}") } - let(:child2_of_child_of_child_by_og) { create(:comment, commentable: article, user: user, ancestry: "#{parent_comment_by_og.id}/#{child_of_parent_by_other.id}/#{child_of_child_by_other.id}") } + let(:child_of_parent_by_other) do + create(:comment, commentable: article, user: other_user, ancestry: parent_comment_by_og.id.to_s) + end + let(:child_of_child_by_og) do + create(:comment, commentable: article, user: user, + ancestry: "#{parent_comment_by_og.id}/#{child_of_parent_by_other.id}") + end + let(:child_of_child_of_child_by_other) do + create(:comment, commentable: article, user: other_user, + ancestry: "#{parent_comment_by_og.id}/#{child_of_parent_by_other.id}/#{child_of_child_by_og.id}") + end + let(:child_of_child_of_child_by_og) do + path = "#{parent_comment_by_og.id}/#{child_of_parent_by_other.id}" + ancestry = "#{path}/#{child_of_child_by_og.id}/#{child_of_child_by_other.id}" + + create(:comment, commentable: article, user: user, ancestry: ancestry) + end + let(:child_of_child_by_other) do + create(:comment, commentable: article, user: other_user, + ancestry: "#{parent_comment_by_og.id}/#{child_of_parent_by_other.id}") + end + let(:child2_of_child_of_child_by_og) do + ancestry = "#{parent_comment_by_og.id}/#{child_of_parent_by_other.id}/#{child_of_child_by_other.id}" + create(:comment, commentable: article, user: user, ancestry: ancestry) + end let(:parent_comment_by_other) { create(:comment, commentable: article, user: other_user) } describe "#show or GET /notification_subscriptions/:notifiable_type/:notifiable_id" do @@ -101,19 +120,26 @@ RSpec.describe "NotificationSubscriptions", type: :request do end it "mutes the parent comment" do - post "/notification_subscriptions/Comment/#{parent_comment_by_og.id}", headers: headers, params: { config: "not_subscribed" } - expect(parent_comment_by_og.reload.receive_notifications).to be false + params = { config: "not_subscribed" } + post "/notification_subscriptions/Comment/#{parent_comment_by_og.id}", headers: headers, params: params + + expect(parent_comment_by_og.reload.receive_notifications).to be(false) end it "does not mute the someone else's parent comment" do - post "/notification_subscriptions/Comment/#{parent_comment_by_og.id}", headers: headers, params: { config: "all_comments" } - expect(parent_comment_by_other.reload.receive_notifications).to be true + params = { config: "all_comments" } + post "/notification_subscriptions/Comment/#{parent_comment_by_og.id}", headers: headers, params: params + + expect(parent_comment_by_other.reload.receive_notifications).to be(true) end it "unmutes the parent comment if already muted" do parent_comment_by_og.update(receive_notifications: false) - post "/notification_subscriptions/Comment/#{parent_comment_by_og.id}", headers: headers, params: { config: "all_comments" } - expect(parent_comment_by_og.reload.receive_notifications).to eq true + + params = { config: "all_comments" } + post "/notification_subscriptions/Comment/#{parent_comment_by_og.id}", headers: headers, params: params + + expect(parent_comment_by_og.reload.receive_notifications).to be(true) end end @@ -124,7 +150,9 @@ RSpec.describe "NotificationSubscriptions", type: :request do child2_of_child_of_child_by_og parent_comment_by_other sign_in user - post "/notification_subscriptions/Comment/#{parent_comment_by_og.id}", headers: headers, params: { config: "not_subscribed" } + + params = { config: "not_subscribed" } + post "/notification_subscriptions/Comment/#{parent_comment_by_og.id}", headers: headers, params: params end it "mutes all of the original commenter's comments in a single thread" do diff --git a/spec/requests/notifications_spec.rb b/spec/requests/notifications_spec.rb index ab5d25578..d04544bca 100644 --- a/spec/requests/notifications_spec.rb +++ b/spec/requests/notifications_spec.rb @@ -172,7 +172,9 @@ RSpec.describe "NotificationsIndex", type: :request do category: categories.sample, ) end - reactions.each { |reaction| Notification.send_reaction_notification_without_delay(reaction, reaction.reactable.user) } + reactions.each do |reaction| + Notification.send_reaction_notification_without_delay(reaction, reaction.reactable.user) + end end it "renders the correct user for a single reaction" do @@ -244,7 +246,9 @@ RSpec.describe "NotificationsIndex", type: :request do reactions = users.map do |user| create(:reaction, user: user, reactable: reactable, category: categories.sample) end - reactions.each { |reaction| Notification.send_reaction_notification_without_delay(reaction, reaction.reactable.organization) } + reactions.each do |reaction| + Notification.send_reaction_notification_without_delay(reaction, reaction.reactable.organization) + end users end @@ -478,8 +482,14 @@ RSpec.describe "NotificationsIndex", type: :request do let(:user2) { create(:user) } let(:article) { create(:article, :with_notification_subscription, user_id: user.id) } let(:comment) { create(:comment, user_id: user2.id, commentable_id: article.id, commentable_type: "Article") } - let(:second_comment) { create(:comment, user_id: user2.id, commentable_id: article.id, commentable_type: "Article", parent_id: comment.id) } - let(:third_comment) { create(:comment, user_id: user2.id, commentable_id: article.id, commentable_type: "Article", parent_id: second_comment.id) } + let(:second_comment) do + create(:comment, user_id: user2.id, commentable_id: article.id, commentable_type: "Article", + parent_id: comment.id) + end + let(:third_comment) do + create(:comment, user_id: user2.id, commentable_id: article.id, commentable_type: "Article", + parent_id: second_comment.id) + end before do sign_in user diff --git a/spec/requests/organizations_update_spec.rb b/spec/requests/organizations_update_spec.rb index 0308c7564..ea99b1f6a 100644 --- a/spec/requests/organizations_update_spec.rb +++ b/spec/requests/organizations_update_spec.rb @@ -32,7 +32,9 @@ RSpec.describe "OrganizationsUpdate", type: :request do end it "updates nav_image" do - put "/organizations/#{org_id}", params: { organization: { id: org_id, nav_image: fixture_file_upload("files/podcast.png", "image/png") } } + put "/organizations/#{org_id}", params: { organization: { id: org_id, + nav_image: fixture_file_upload("files/podcast.png", + "image/png") } } expect(Organization.find(org_id).nav_image_url).to be_present end diff --git a/spec/requests/page_views_spec.rb b/spec/requests/page_views_spec.rb index 06a3563c2..957f57e34 100644 --- a/spec/requests/page_views_spec.rb +++ b/spec/requests/page_views_spec.rb @@ -48,7 +48,8 @@ RSpec.describe "PageViews", type: :request do article_id: article.id, referrer: "test" } - expect(Users::RecordFieldTestEventWorker).to have_received(:perform_async).with(user.id, :user_home_feed, "user_views_article_four_days_in_week") + expect(Users::RecordFieldTestEventWorker).to have_received(:perform_async). + with(user.id, :user_home_feed, "user_views_article_four_days_in_week") end end diff --git a/spec/requests/pages_spec.rb b/spec/requests/pages_spec.rb index 134e44d45..90f8f6609 100644 --- a/spec/requests/pages_spec.rb +++ b/spec/requests/pages_spec.rb @@ -19,7 +19,9 @@ RSpec.describe "Pages", type: :request do context "when json template" do let_it_be(:json_text) { "{\"foo\": \"bar\"}" } - let_it_be(:page) { create(:page, title: "sample_data", template: "json", body_json: json_text, body_html: nil, body_markdown: nil) } + let_it_be(:page) do + create(:page, title: "sample_data", template: "json", body_json: json_text, body_html: nil, body_markdown: nil) + end before do page.save! # Trigger processing of page.body_html @@ -170,7 +172,9 @@ RSpec.describe "Pages", type: :request do describe "GET /robots.txt" do it "has proper text" do get "/robots.txt" - expect(response.body).to include("Sitemap: https://#{ApplicationConfig['AWS_BUCKET_NAME']}.s3.amazonaws.com/sitemaps/sitemap.xml.gz") + + text = "Sitemap: https://#{ApplicationConfig['AWS_BUCKET_NAME']}.s3.amazonaws.com/sitemaps/sitemap.xml.gz" + expect(response.body).to include(text) end end diff --git a/spec/requests/partnerships_spec.rb b/spec/requests/partnerships_spec.rb index 005380c0c..62b1c715e 100644 --- a/spec/requests/partnerships_spec.rb +++ b/spec/requests/partnerships_spec.rb @@ -137,13 +137,15 @@ RSpec.describe "Partnerships", type: :request do end it "displays info about an existing sponsorship" do - create(:sponsorship, level: :tag, organization: org, user: user, sponsorable: ruby, expires_at: 3.days.from_now) + create(:sponsorship, level: :tag, organization: org, user: user, sponsorable: ruby, + expires_at: 3.days.from_now) get "/partnerships/tag-sponsor" expect(response.body).to include("You are Subscribed as the sponsor of #ruby") end it "doesn't display info about an expired sponsorship" do - create(:sponsorship, level: :tag, organization: org, user: user, sponsorable: ruby, expires_at: 3.days.ago) + create(:sponsorship, level: :tag, organization: org, user: user, sponsorable: ruby, + expires_at: 3.days.ago) get "/partnerships/tag-sponsor" expect(response.body).not_to include("You are Subscribed as the sponsor of #ruby") end @@ -155,7 +157,8 @@ RSpec.describe "Partnerships", type: :request do end it "displays info about an existing sponsorship" do - create(:sponsorship, level: :tag, organization: org, user: user, sponsorable: ruby, expires_at: 3.days.from_now) + create(:sponsorship, level: :tag, organization: org, user: user, sponsorable: ruby, + expires_at: 3.days.from_now) get "/partnerships/tag-sponsor" expect(response.body).to include("You are Subscribed as the sponsor of #ruby") end diff --git a/spec/requests/reactions_spec.rb b/spec/requests/reactions_spec.rb index d4e26230a..ea8747863 100644 --- a/spec/requests/reactions_spec.rb +++ b/spec/requests/reactions_spec.rb @@ -300,7 +300,8 @@ RSpec.describe "Reactions", type: :request do it "converts field test" do post "/reactions", params: article_params - expect(Users::RecordFieldTestEventWorker).to have_received(:perform_async).with(user.id, :user_home_feed, "user_creates_reaction") + expect(Users::RecordFieldTestEventWorker).to have_received(:perform_async).with(user.id, :user_home_feed, + "user_creates_reaction") end end diff --git a/spec/requests/response_templates_spec.rb b/spec/requests/response_templates_spec.rb index e2ce2ae65..61e6b2b6c 100644 --- a/spec/requests/response_templates_spec.rb +++ b/spec/requests/response_templates_spec.rb @@ -27,7 +27,10 @@ RSpec.describe "ResponseTemplate", type: :request do it "returns an array of all the user's response templates" do total_response_templates = 2 create_list(:response_template, total_response_templates, user: user, type_of: "personal_comment") - get response_templates_path, params: { type_of: "personal_comment" }, headers: { HTTP_ACCEPT: "application/json" } + + headers = { HTTP_ACCEPT: "application/json" } + get response_templates_path, params: { type_of: "personal_comment" }, headers: headers + expect(response.parsed_body.class).to eq Array expect(response.parsed_body.length).to eq total_response_templates end @@ -35,9 +38,12 @@ RSpec.describe "ResponseTemplate", type: :request do it "returns only the users' response templates" do create(:response_template, user: nil, type_of: "mod_comment") create_list(:response_template, 2, user: user, type_of: "personal_comment") - get response_templates_path, params: { type_of: "personal_comment" }, headers: { HTTP_ACCEPT: "application/json" } - user_ids = JSON.parse(response.body).map { |hash| hash["user_id"] } - expect(user_ids).to eq [user.id, user.id] + + headers = { HTTP_ACCEPT: "application/json" } + get response_templates_path, params: { type_of: "personal_comment" }, headers: headers + + user_ids = response.parsed_body.map { |hash| hash["user_id"] } + expect(user_ids).to eq([user.id, user.id]) end it "raises an error if trying to view moderator response templates" do @@ -128,7 +134,8 @@ RSpec.describe "ResponseTemplate", type: :request do content: attributes[:content] } } - expect(response.redirect_url).to include user_settings_path(tab: "response-templates", id: ResponseTemplate.last.id) + expect(response.redirect_url).to include user_settings_path(tab: "response-templates", + id: ResponseTemplate.last.id) end end @@ -145,7 +152,8 @@ RSpec.describe "ResponseTemplate", type: :request do it "redirects back to the response template" do patch response_template_path(response_template.id), params: { response_template: { title: "something else" } } - expect(response.redirect_url).to include user_settings_path(tab: "response-templates", id: ResponseTemplate.first.id) + expect(response.redirect_url).to include user_settings_path(tab: "response-templates", + id: ResponseTemplate.first.id) end it "shows the previously written content on a failed submission" do diff --git a/spec/requests/sitemaps_spec.rb b/spec/requests/sitemaps_spec.rb index 085bf5291..8807ea85f 100644 --- a/spec/requests/sitemaps_spec.rb +++ b/spec/requests/sitemaps_spec.rb @@ -29,9 +29,13 @@ RSpec.describe "Sitemaps", type: :request do articles = create_list(:article, 4) included_articles = articles.first(3) included_articles.each { |a| a.update(published_at: "2020-03-07T00:27:30Z", score: 10) } + get "/sitemap-Mar-2020.xml" + article = included_articles.first - expect(response.body).to include("#{ApplicationConfig['APP_PROTOCOL']}#{ApplicationConfig['APP_DOMAIN']}#{article.path}") + + expected_tag = "#{ApplicationConfig['APP_PROTOCOL']}#{ApplicationConfig['APP_DOMAIN']}#{article.path}" + expect(response.body).to include(expected_tag) expect(response.body).to include("#{article.last_comment_at.strftime('%F')}") expect(response.body).not_to include(articles.last.path) expect(response.media_type).to eq("application/xml") diff --git a/spec/requests/stories_index_spec.rb b/spec/requests/stories_index_spec.rb index e56e664f4..f733df249 100644 --- a/spec/requests/stories_index_spec.rb +++ b/spec/requests/stories_index_spec.rb @@ -407,7 +407,9 @@ RSpec.describe "StoriesIndex", type: :request do it "renders proper canonical url for page 2" do get "/t/#{tag.name}/page/2" - expect(response.body).to include("") + + expected_tag = "" + expect(response.body).to include(expected_tag) end end end diff --git a/spec/requests/stories_show_spec.rb b/spec/requests/stories_show_spec.rb index 7f1c5005c..7b2985c99 100644 --- a/spec/requests/stories_show_spec.rb +++ b/spec/requests/stories_show_spec.rb @@ -23,7 +23,9 @@ RSpec.describe "StoriesShow", type: :request do it "renders signed-in title tag for signed-in user" do sign_in user get article.path - expect(response.body).to include "#{CGI.escapeHTML(article.title)} - #{community_qualified_name} 👩‍💻👨‍💻" + + expected_title = "#{CGI.escapeHTML(article.title)} - #{community_qualified_name} 👩‍💻👨‍💻" + expect(response.body).to include(expected_title) end it "renders signed-out title tag for signed-out user" do @@ -36,37 +38,41 @@ RSpec.describe "StoriesShow", type: :request do it "renders title tag with search_optimized_title_preamble if set and not signed in" do article.update_column(:search_optimized_title_preamble, "Hey this is a test") get article.reload.path - expect(response.body).to include "Hey this is a test: #{CGI.escapeHTML(article.title)} - #{community_name}" + + expected_title = "Hey this is a test: #{CGI.escapeHTML(article.title)} - #{community_name}" + expect(response.body).to include(expected_title) end it "does not render title tag with search_optimized_title_preamble if set and not signed in" do sign_in user article.update_column(:search_optimized_title_preamble, "Hey this is a test") get article.path - expect(response.body).to include "#{CGI.escapeHTML(article.title)} - #{community_qualified_name} 👩‍💻👨‍💻" + + expected_title = "#{CGI.escapeHTML(article.title)} - #{community_qualified_name} 👩‍💻👨‍💻" + expect(response.body).to include(expected_title) end - it "does not render preamble with search_optimized_title_preamble not signed in but search_optimized_title_preamble not set" do + it "does not render preamble with search_optimized_title_preamble not signed in but not set" do get article.path - expect(response.body).to include "#{CGI.escapeHTML(article.title)} - #{community_name}" + expect(response.body).to include("#{CGI.escapeHTML(article.title)} - #{community_name}") end it "renders title preamble with search_optimized_title_preamble if set and not signed in" do article.update_column(:search_optimized_title_preamble, "Hey this is a test") get article.reload.path - expect(response.body).to include "Hey this is a test" + expect(response.body).to include("Hey this is a test") end it "does not render preamble with search_optimized_title_preamble if set and signed in" do sign_in user article.update_column(:search_optimized_title_preamble, "Hey this is a test") get article.path - expect(response.body).not_to include "Hey this is a test" + expect(response.body).not_to include("Hey this is a test") end - it "does not render title tag with search_optimized_title_preamble not signed in but search_optimized_title_preamble not set" do + it "does not render title tag with search_optimized_title_preamble not signed in but not set" do get article.path - expect(response.body).not_to include "Hey this is a test" + expect(response.body).not_to include("Hey this is a test") end it "renders user payment pointer if set" do diff --git a/spec/requests/tag_adjustments_spec.rb b/spec/requests/tag_adjustments_spec.rb index 80befa6c6..1151e5043 100644 --- a/spec/requests/tag_adjustments_spec.rb +++ b/spec/requests/tag_adjustments_spec.rb @@ -25,7 +25,12 @@ RSpec.describe "TagAdjustments", type: :request do end context "when an article doesn't use front matter" do - let(:article) { Article.create(user: user, title: "something", body_markdown: "blah blah #{rand(100)}", tag_list: "#{tag.name}, yoyo, bobo", published: true) } + let(:article) do + Article.create( + user: user, title: "something", body_markdown: "blah blah #{rand(100)}", + tag_list: "#{tag.name}, yoyo, bobo", published: true + ) + end it "removes the tag" do expect(article.reload.tag_list.include?(tag.name)).to be false @@ -37,7 +42,10 @@ RSpec.describe "TagAdjustments", type: :request do end context "when an article uses front matter" do - let(:article) { create(:article, user: user, body_markdown: "---\ntitle: Hellohnnnn#{rand(1000)}\npublished: true\ntags: heyheyhey,#{tag.name}\n---\n\nHello") } + let(:article) do + body = "---\ntitle: Hellohnnnn#{rand(1000)}\npublished: true\ntags: heyheyhey,#{tag.name}\n---\n\nHello" + create(:article, user: user, body_markdown: body) + end it "removes the tag" do expect(article.reload.tag_list.include?(tag.name)).to be false @@ -62,7 +70,12 @@ RSpec.describe "TagAdjustments", type: :request do end context "when an article doesn't use front matter" do - let(:article) { Article.create(user: user, title: "something", body_markdown: "blah blah #{rand(100)}", tag_list: "yoyo, bobo", published: true) } + let(:article) do + Article.create( + user: user, title: "something", body_markdown: "blah blah #{rand(100)}", + tag_list: "yoyo, bobo", published: true + ) + end it "adds the tag" do expect(article.reload.tag_list.include?(tag.name)).to be true @@ -74,7 +87,10 @@ RSpec.describe "TagAdjustments", type: :request do end context "when an article uses front matter" do - let(:article) { create(:article, user: user, body_markdown: "---\ntitle: Hellohnnnn#{rand(1000)}\npublished: true\ntags: heyheyhey\n---\n\nHello") } + let(:article) do + body_markdown = "---\ntitle: Hellohnnnn#{rand(1000)}\npublished: true\ntags: heyheyhey\n---\n\nHello" + create(:article, user: user, body_markdown: body_markdown) + end it "adds the tag" do expect(article.reload.tag_list.include?(tag.name)).to be true @@ -97,7 +113,10 @@ RSpec.describe "TagAdjustments", type: :request do end context "when an article doesn't use front matter" do - let(:article) { Article.create(user: user, title: "something", body_markdown: "blah blah #{rand(100)}", tag_list: "#{tag.name}, yoyo, bobo", published: true) } + let(:article) do + Article.create(user: user, title: "something", body_markdown: "blah blah #{rand(100)}", + tag_list: "#{tag.name}, yoyo, bobo", published: true) + end it "adds the tag back in" do delete "/tag_adjustments/#{tag_adjustment.id}", params: { @@ -108,7 +127,10 @@ RSpec.describe "TagAdjustments", type: :request do end context "when an article uses front matter" do - let(:article) { create(:article, user: user, body_markdown: "---\ntitle: Hellohnnnn#{rand(1000)}\npublished: true\ntags: heyheyhey,#{tag.name}\n---\n\nHello") } + let(:article) do + body = "---\ntitle: Hellohnnnn#{rand(1000)}\npublished: true\ntags: heyheyhey,#{tag.name}\n---\n\nHello" + create(:article, user: user, body_markdown: body) + end it "adds the tag back in" do delete "/tag_adjustments/#{tag_adjustment.id}", params: { @@ -120,7 +142,9 @@ RSpec.describe "TagAdjustments", type: :request do end describe "DELETE /tag_adjustments/:id with adjustment_type addition" do - let(:tag_adjustment) { create(:tag_adjustment, article_id: article.id, user: user, tag: tag, adjustment_type: "addition") } + let(:tag_adjustment) do + create(:tag_adjustment, article_id: article.id, user: user, tag: tag, adjustment_type: "addition") + end before do user.add_role(:admin) @@ -130,7 +154,10 @@ RSpec.describe "TagAdjustments", type: :request do end context "when an article doesn't use front matter" do - let(:article) { Article.create(user: user, title: "something", body_markdown: "blah blah #{rand(100)}", tag_list: "yoyo, bobo", published: true) } + let(:article) do + Article.create(user: user, title: "something", body_markdown: "blah blah #{rand(100)}", tag_list: "yoyo, bobo", + published: true) + end it "removes the added tag" do delete "/tag_adjustments/#{tag_adjustment.id}", params: { @@ -141,7 +168,10 @@ RSpec.describe "TagAdjustments", type: :request do end context "when an article uses front matter" do - let(:article) { create(:article, user: user, body_markdown: "---\ntitle: Hellohnnnn#{rand(1000)}\npublished: true\ntags: heyheyhey\n---\n\nHello") } + let(:article) do + body_markdown = "---\ntitle: Hellohnnnn#{rand(1000)}\npublished: true\ntags: heyheyhey\n---\n\nHello" + create(:article, user: user, body_markdown: body_markdown) + end it "removes the added tag" do delete "/tag_adjustments/#{tag_adjustment.id}", params: { diff --git a/spec/requests/twitch_stream_updates_spec.rb b/spec/requests/twitch_stream_updates_spec.rb index 2eb6d056e..861b4ebe1 100644 --- a/spec/requests/twitch_stream_updates_spec.rb +++ b/spec/requests/twitch_stream_updates_spec.rb @@ -3,6 +3,26 @@ require "rails_helper" RSpec.describe "TwitchStramUpdates", type: :request do let(:user) { create(:user, twitch_username: "my-twtich-username", currently_streaming_on: currently_streaming_on) } let(:currently_streaming_on) { nil } + let(:twitch_webhook_params) do + { + "data" => + [ + { + "id" => "0123456789", + "user_id" => "5678", + "user_name" => "wjdtkdqhs", + "game_id" => "21779", + "community_ids" => [], + "type" => "live", + "title" => "Best Stream Ever", + "viewer_count" => 417, + "started_at" => "2017-12-01T10:09:45Z", + "language" => "en", + "thumbnail_url" => "https://link/to/thumbnail.jpg" + }, + ] + }.to_json + end describe "GET /users/:user_id/twitch_stream_updates" do context "when the subscription was successful" do @@ -48,29 +68,30 @@ RSpec.describe "TwitchStramUpdates", type: :request do context "when the user was not streaming and starts streaming" do let(:currently_streaming_on) { nil } - - let(:twitch_webhook_params) do - '{"data":[{"id":"0123456789","user_id":"5678","user_name":"wjdtkdqhs","game_id":"21779","community_ids":[],"type":"live","title":"Best Stream Ever","viewer_count":417,"started_at":"2017-12-01T10:09:45Z","language":"en","thumbnail_url":"https://link/to/thumbnail.jpg"}]}' - end let(:twitch_webhook_secret_sha) do "sha256=96840ed4d83666551e43b384d94ac481367504564d6474b5dea710cedde5ce18" end it "updates the Users twitch streaming status" do - expect { post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params, headers: { "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha } }. + expect do + post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params, headers: { + "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha + } + end. to change { user.reload.currently_streaming? }.from(false).to(true). and change { user.reload.currently_streaming_on_twitch? }.from(false).to(true) end end context "when the webhook secret was NOT verified" do - let(:twitch_webhook_params) do - '{"data":[{"id":"0123456789","user_id":"5678","user_name":"wjdtkdqhs","game_id":"21779","community_ids":[],"type":"live","title":"Best Stream Ever","viewer_count":417,"started_at":"2017-12-01T10:09:45Z","language":"en","thumbnail_url":"https://link/to/thumbnail.jpg"}]}' - end let(:twitch_webhook_secret_sha) { "sha256=BAD_HASH" } it "noops" do - expect { post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params, headers: { "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha } }. + expect do + post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params, headers: { + "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha + } + end. to not_change { user.reload.currently_streaming? }.from(false). and not_change { user.reload.currently_streaming_on_twitch? }.from(false) end @@ -87,7 +108,11 @@ RSpec.describe "TwitchStramUpdates", type: :request do end it "updates the Users twitch streaming status" do - expect { post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params, headers: { "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha } }. + expect do + post "/users/#{user.id}/twitch_stream_updates", params: twitch_webhook_params, headers: { + "Content-Type" => "application/json", "X-Hub-Signature" => twitch_webhook_secret_sha + } + end. to change { user.reload.currently_streaming? }.from(true).to(false). and change { user.reload.currently_streaming_on_twitch? }.from(true).to(false) end diff --git a/spec/requests/user/user_organization_spec.rb b/spec/requests/user/user_organization_spec.rb index 6c2f85726..3c1be9313 100644 --- a/spec/requests/user/user_organization_spec.rb +++ b/spec/requests/user/user_organization_spec.rb @@ -34,7 +34,9 @@ RSpec.describe "UserOrganization", type: :request do before do sign_in user - org_params["profile_image"] = Rack::Test::UploadedFile.new(Rails.root.join("app/assets/images/android-icon-36x36.png"), "image/jpeg") + org_params["profile_image"] = Rack::Test::UploadedFile.new( + Rails.root.join("app/assets/images/android-icon-36x36.png"), "image/jpeg" + ) allow(RateLimitChecker).to receive(:new).and_return(rate_limiter) allow(rate_limiter).to receive(:limit_by_action).and_return(false) end diff --git a/spec/requests/user/user_settings_spec.rb b/spec/requests/user/user_settings_spec.rb index 4dd8df752..20d8ac092 100644 --- a/spec/requests/user/user_settings_spec.rb +++ b/spec/requests/user/user_settings_spec.rb @@ -399,8 +399,8 @@ RSpec.describe "UserSettings", type: :request do delete "/users/remove_identity", params: { provider: provider } expect(response).to redirect_to("/settings/account") - expected_error = "An error occurred. Please try again or send an email to: #{SiteConfig.email_addresses[:default]}" - expect(flash[:error]).to eq(expected_error) + error = "An error occurred. Please try again or send an email to: #{SiteConfig.email_addresses[:default]}" + expect(flash[:error]).to eq(error) end it "does not show the 'Remove OAuth' section afterwards if only one identity remains" do @@ -423,8 +423,8 @@ RSpec.describe "UserSettings", type: :request do it "sets the proper flash error message" do delete "/users/remove_identity", params: { provider: provider } - expected_error = "An error occurred. Please try again or send an email to: #{SiteConfig.email_addresses[:default]}" - expect(flash[:error]).to eq(expected_error) + error = "An error occurred. Please try again or send an email to: #{SiteConfig.email_addresses[:default]}" + expect(flash[:error]).to eq(error) end it "does not delete any identities" do diff --git a/spec/requests/user_blocks_spec.rb b/spec/requests/user_blocks_spec.rb index 2609d69af..067dffc46 100644 --- a/spec/requests/user_blocks_spec.rb +++ b/spec/requests/user_blocks_spec.rb @@ -52,7 +52,8 @@ RSpec.describe "UserBlock", type: :request do end it "blocks the potential chat channel" do - chat_channel = create(:chat_channel, channel_type: "direct", slug: "#{blocker.username}/#{blocked.username}", status: "active") + chat_channel = create(:chat_channel, channel_type: "direct", slug: "#{blocker.username}/#{blocked.username}", + status: "active") create(:chat_channel_membership, chat_channel_id: chat_channel.id, user_id: blocker.id) create(:chat_channel_membership, chat_channel_id: chat_channel.id, user_id: blocked.id) post "/user_blocks", params: { user_block: { blocked_id: blocked.id } } @@ -96,7 +97,8 @@ RSpec.describe "UserBlock", type: :request do end it "unblocks the direct chat channel" do - chat_channel = create(:chat_channel, channel_type: "direct", slug: "#{blocker.username}/#{blocked.username}", status: "blocked") + chat_channel = create(:chat_channel, channel_type: "direct", slug: "#{blocker.username}/#{blocked.username}", + status: "blocked") create(:chat_channel_membership, chat_channel_id: chat_channel.id, user_id: blocker.id) create(:chat_channel_membership, chat_channel_id: chat_channel.id, user_id: blocked.id) delete "/user_blocks/#{blocked.id}", params: { user_block: { blocked_id: blocked.id } } diff --git a/spec/requests/user_subscriptions_spec.rb b/spec/requests/user_subscriptions_spec.rb index 8d4a36e00..c7ccdde9f 100644 --- a/spec/requests/user_subscriptions_spec.rb +++ b/spec/requests/user_subscriptions_spec.rb @@ -53,7 +53,8 @@ RSpec.describe "UserSubscriptions", type: :request do end it "returns an error for an invalid source_type" do - invalid_source_type_attributes = { source_type: "NonExistentSourceType", source_id: "1", subscriber_email: user.email } + invalid_source_type_attributes = { source_type: "NonExistentSourceType", source_id: "1", + subscriber_email: user.email } expect do post user_subscriptions_path, headers: { "Content-Type" => "application/json" }, @@ -77,8 +78,10 @@ RSpec.describe "UserSubscriptions", type: :request do end it "returns an error for an inactive source" do - unpublished_article = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true, published: false) - invalid_source_attributes = { source_type: unpublished_article.class_name, source_id: unpublished_article.id, subscriber_email: user.email } + unpublished_article = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true, + published: false) + invalid_source_attributes = { source_type: unpublished_article.class_name, source_id: unpublished_article.id, + subscriber_email: user.email } expect do post user_subscriptions_path, headers: { "Content-Type" => "application/json" }, @@ -91,7 +94,8 @@ RSpec.describe "UserSubscriptions", type: :request do it "returns an error for a source that doesn't have the UserSubscription liquid tag enabled" do article = create(:article, :with_user_subscription_tag_role_user) - invalid_source_attributes = { source_type: article.class_name, source_id: article.id, subscriber_email: user.email } + invalid_source_attributes = { source_type: article.class_name, source_id: article.id, + subscriber_email: user.email } expect do post user_subscriptions_path, headers: { "Content-Type" => "application/json" }, @@ -113,7 +117,8 @@ RSpec.describe "UserSubscriptions", type: :request do author_id: article.user.id, user_subscription_sourceable: article) - invalid_source_attributes = { source_type: article.class_name, source_id: article.id, subscriber_email: user.email } + invalid_source_attributes = { source_type: article.class_name, source_id: article.id, + subscriber_email: user.email } expect do post user_subscriptions_path, @@ -128,7 +133,8 @@ RSpec.describe "UserSubscriptions", type: :request do # TODO: [@thepracticaldev/delightful]: re-enable this once email confirmation is re-enabled xit "returns an error for an email mismatch" do article = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true) - invalid_source_attributes = { source_type: article.class_name, source_id: article.id, subscriber_email: "old_email@test.com" } + invalid_source_attributes = { source_type: article.class_name, source_id: article.id, + subscriber_email: "old_email@test.com" } expect do post user_subscriptions_path, @@ -152,7 +158,8 @@ RSpec.describe "UserSubscriptions", type: :request do end.to change(UserSubscription, :count).by(0) expect(response).to have_http_status(:unprocessable_entity) - expect(response.parsed_body["error"]).to include("Subscriber email Can't subscribe with an Apple private relay. Please update email.") + error_message = "Subscriber email Can't subscribe with an Apple private relay. Please update email." + expect(response.parsed_body["error"]).to include(error_message) end end diff --git a/spec/services/articles/analytics_updater_spec.rb b/spec/services/articles/analytics_updater_spec.rb index eb3185b45..925ec094f 100644 --- a/spec/services/articles/analytics_updater_spec.rb +++ b/spec/services/articles/analytics_updater_spec.rb @@ -19,7 +19,9 @@ RSpec.describe Articles::AnalyticsUpdater, type: :service do end context "when public_reactions_count is HIGHER than previous_public_reactions_count" do - let(:article) { build_stubbed(:article, public_reactions_count: 5, previous_public_reactions_count: 3, user: user) } + let(:article) do + build_stubbed(:article, public_reactions_count: 5, previous_public_reactions_count: 3, user: user) + end let(:pageview) { {} } let(:counts) { 1000 } let(:user_articles) { double } @@ -40,7 +42,8 @@ RSpec.describe Articles::AnalyticsUpdater, type: :service do end it "updates appropriate column" do - expect(article).to have_received(:update_columns).with(previous_public_reactions_count: article.public_reactions_count) + count = article.public_reactions_count + expect(article).to have_received(:update_columns).with(previous_public_reactions_count: count) end end end diff --git a/spec/services/articles/builder_spec.rb b/spec/services/articles/builder_spec.rb index b0b844f06..b3fcac54b 100644 --- a/spec/services/articles/builder_spec.rb +++ b/spec/services/articles/builder_spec.rb @@ -128,8 +128,11 @@ RSpec.describe Articles::Builder, type: :service do context "when user_editor_v1" do let(:correct_attributes) do + body = "---\ntitle: \npublished: false\ndescription: \ntags: " \ + "\n//cover_image: https://direct_url_to_image.jpg\n---\n\n" + { - body_markdown: "---\ntitle: \npublished: false\ndescription: \ntags: \n//cover_image: https://direct_url_to_image.jpg\n---\n\n", + body_markdown: body, processed_html: "", user_id: user.id } diff --git a/spec/services/authentication/providers/twitter_spec.rb b/spec/services/authentication/providers/twitter_spec.rb index 9781e7b3e..d92781587 100644 --- a/spec/services/authentication/providers/twitter_spec.rb +++ b/spec/services/authentication/providers/twitter_spec.rb @@ -15,7 +15,8 @@ RSpec.describe Authentication::Providers::Twitter, type: :service do describe ".sign_in_path" do let(:expected_path) do - "/users/auth/twitter?callback_url=http%3A%2F%2Flocalhost%3A3000%2Fusers%2Fauth%2Ftwitter%2Fcallback&secure_image_url=true" + "/users/auth/twitter?callback_url=" \ + "http%3A%2F%2Flocalhost%3A3000%2Fusers%2Fauth%2Ftwitter%2Fcallback&secure_image_url=true" end it "returns the correct sign in path" do diff --git a/spec/services/broadcasts/welcome_notification/generator_spec.rb b/spec/services/broadcasts/welcome_notification/generator_spec.rb index a36b71edd..9ac72065d 100644 --- a/spec/services/broadcasts/welcome_notification/generator_spec.rb +++ b/spec/services/broadcasts/welcome_notification/generator_spec.rb @@ -45,27 +45,51 @@ RSpec.describe Broadcasts::WelcomeNotification::Generator, type: :service do it "sends only 1 notification at a time, in the correct order" do user.update!(created_at: 1.day.ago) - expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect do + sidekiq_perform_enqueued_jobs do + described_class.call(user.id) + end + end.to change(user.notifications, :count).by(1) expect(user.notifications.last.notifiable).to eq(welcome_broadcast) Timecop.travel(1.day.since) - expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect do + sidekiq_perform_enqueued_jobs do + described_class.call(user.id) + end + end.to change(user.notifications, :count).by(1) expect(user.notifications.last.notifiable).to eq(twitter_connect_broadcast) Timecop.travel(1.day.since) - expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect do + sidekiq_perform_enqueued_jobs do + described_class.call(user.id) + end + end.to change(user.notifications, :count).by(1) expect(user.notifications.last.notifiable).to eq(customize_feed_broadcast) Timecop.travel(2.days.since) - expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect do + sidekiq_perform_enqueued_jobs do + described_class.call(user.id) + end + end.to change(user.notifications, :count).by(1) expect(user.notifications.last.notifiable).to eq(customize_ux_broadcast) Timecop.travel(1.day.since) - expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect do + sidekiq_perform_enqueued_jobs do + described_class.call(user.id) + end + end.to change(user.notifications, :count).by(1) expect(user.notifications.last.notifiable).to eq(discuss_and_ask_broadcast) Timecop.travel(1.day.since) - expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect do + sidekiq_perform_enqueued_jobs do + described_class.call(user.id) + end + end.to change(user.notifications, :count).by(1) expect(user.notifications.last.notifiable).to eq(download_app_broadcast) Timecop.return end diff --git a/spec/services/bulk_sql_delete_spec.rb b/spec/services/bulk_sql_delete_spec.rb index 3ffecf8b6..9a380e400 100644 --- a/spec/services/bulk_sql_delete_spec.rb +++ b/spec/services/bulk_sql_delete_spec.rb @@ -29,7 +29,8 @@ describe BulkSqlDelete, type: :service do it "logs errors that occur" do allow(logger).to receive(:error) # rubocop:disable RSpec/AnyInstance - allow_any_instance_of(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter).to receive(:exec_delete).and_raise("broken") + allow_any_instance_of(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter). + to(receive(:exec_delete)).and_raise("broken") # rubocop:enable RSpec/AnyInstance expect { described_class.delete_in_batches(sql) }.to raise_error("broken") diff --git a/spec/services/fastly_config/snippets_spec.rb b/spec/services/fastly_config/snippets_spec.rb index 55172b594..df3017303 100644 --- a/spec/services/fastly_config/snippets_spec.rb +++ b/spec/services/fastly_config/snippets_spec.rb @@ -45,7 +45,8 @@ RSpec.describe FastlyConfig::Snippets, type: :service do snippets_config.update(fastly_version) - tags = hash_including(tags: array_including("snippet_update_type:update", "snippet_name:test", "new_version:#{fastly_version.number}")) + tags = hash_including(tags: array_including("snippet_update_type:update", "snippet_name:test", + "new_version:#{fastly_version.number}")) expect(DatadogStatsClient).to have_received(:increment).with("fastly.snippets", tags).at_least(:once) end diff --git a/spec/services/notifications/milestone/send_spec.rb b/spec/services/notifications/milestone/send_spec.rb index 4010c8095..5d5b775a5 100644 --- a/spec/services/notifications/milestone/send_spec.rb +++ b/spec/services/notifications/milestone/send_spec.rb @@ -47,16 +47,17 @@ RSpec.describe Notifications::Milestone::Send, type: :service do expect(user.notifications.count).to eq 2 end - it "does not send a view milestone notification again if the latest number of views is not past the next milestone" do + it "does not send a view milestone notification again if the latest num of views isn't past the next milestone" do article.update_column(:page_views_count, rand(9002..16_383)) send_milestone_notification_view expect(user.notifications.count).to eq 2 end it "checks notification json data", :aggregate_failures do - expect(user.notifications.where(notifiable_type: "Article").first.json_data["article"]["class"]["name"]).to eq "Article" - expect(user.notifications.where(notifiable_id: article.id).first.json_data["article"]["id"]).to eq article.id - expect(user.notifications.where(notifiable_id: article.id).first.json_data["article"]["title"]).to eq article.title + nots = user.notifications + expect(nots.where(notifiable_type: "Article").first.json_data["article"]["class"]["name"]).to eq("Article") + expect(nots.where(notifiable_id: article.id).first.json_data["article"]["id"]).to eq(article.id) + expect(nots.where(notifiable_id: article.id).first.json_data["article"]["title"]).to eq(article.title) end end diff --git a/spec/services/notifications/new_comment/send_spec.rb b/spec/services/notifications/new_comment/send_spec.rb index df061a16d..cee757697 100644 --- a/spec/services/notifications/new_comment/send_spec.rb +++ b/spec/services/notifications/new_comment/send_spec.rb @@ -59,7 +59,8 @@ RSpec.describe Notifications::NewComment::Send, type: :service do it "creates author comments notification" do create(:notification_subscription, user: user3, notifiable: article, config: "only_author_comments") described_class.call(author_comment) - notified_user_ids = Notification.where(notifiable_type: "Comment", notifiable_id: author_comment.reload.id).pluck(:user_id) + notified_user_ids = Notification.where(notifiable_type: "Comment", + notifiable_id: author_comment.reload.id).pluck(:user_id) expect(notified_user_ids.sort).to eq([user3.id].sort) end @@ -86,7 +87,8 @@ RSpec.describe Notifications::NewComment::Send, type: :service do it "creates an organization notification" do article.update_column(:organization_id, organization.id) described_class.call(child_comment) - expect(Notification.where(notifiable_type: "Comment", notifiable_id: child_comment.id, organization_id: organization.id)).to be_any + expect(Notification.where(notifiable_type: "Comment", notifiable_id: child_comment.id, + organization_id: organization.id)).to be_any end it "sends Push Notifications using Pusher Beams when configured" do @@ -101,6 +103,7 @@ RSpec.describe Notifications::NewComment::Send, type: :service do channels = ["user-notifications-#{user2.id}", "user-notifications-#{user.id}"] payload = described_class.new(comment_sent).send(:push_notification_payload) - expect(Pusher::PushNotifications).to have_received(:publish_to_interests).with(interests: channels, payload: payload) + expect(Pusher::PushNotifications).to have_received(:publish_to_interests).with(interests: channels, + payload: payload) end end diff --git a/spec/services/notifications/reactions/send_spec.rb b/spec/services/notifications/reactions/send_spec.rb index b250f2339..a4cf4a5b2 100644 --- a/spec/services/notifications/reactions/send_spec.rb +++ b/spec/services/notifications/reactions/send_spec.rb @@ -64,7 +64,9 @@ RSpec.describe Notifications::Reactions::Send, type: :service do expect(notification.json_data["user"]["name"]).to eq(user2.name) expect(notification.json_data["reaction"]["reactable_id"]).to eq(article.id) expect(notification.json_data["reaction"]["aggregated_siblings"].size).to eq(2) - expect(notification.json_data["reaction"]["aggregated_siblings"].map { |s| s["user"]["id"] }.sort).to eq([user2.id, user3.id].sort) + expect(notification.json_data["reaction"]["aggregated_siblings"].map do |s| + s["user"]["id"] + end.sort).to eq([user2.id, user3.id].sort) end context "when notification exists" do diff --git a/spec/services/notifications/remove_all_by_action_spec.rb b/spec/services/notifications/remove_all_by_action_spec.rb index 74b93e0c4..e922c479c 100644 --- a/spec/services/notifications/remove_all_by_action_spec.rb +++ b/spec/services/notifications/remove_all_by_action_spec.rb @@ -11,7 +11,8 @@ RSpec.describe Notifications::RemoveAllByAction, type: :service do before do create(:notification, user: user, notifiable_id: article.id, notifiable_type: "Article", action: "Published") create(:notification, user: user2, notifiable_id: article.id, notifiable_type: "Article", action: "Published") - create(:notification, organization: organization, notifiable_id: comment.id, notifiable_type: "Comment", action: "Reaction") + create(:notification, organization: organization, notifiable_id: comment.id, notifiable_type: "Comment", + action: "Reaction") end it "checks all notifications for an article are deleted and only for an article" do diff --git a/spec/services/notifications/tag_adjustment_notification/send_spec.rb b/spec/services/notifications/tag_adjustment_notification/send_spec.rb index cb11e36cb..c6c9b308e 100644 --- a/spec/services/notifications/tag_adjustment_notification/send_spec.rb +++ b/spec/services/notifications/tag_adjustment_notification/send_spec.rb @@ -3,10 +3,15 @@ require "rails_helper" RSpec.describe Notifications::TagAdjustmentNotification::Send, type: :service do let(:user) { create(:user) } let(:user2) { create(:user) } - let(:article) { create(:article, title: "My title", user: user2, body_markdown: "---\ntitle: Hellohnnnn#{rand(1000)}\npublished: true\ntags: heyheyhey,#{tag.name}\n---\n\nHello") } + let(:article) do + body_markdown = "---\ntitle: Hellohnnnn#{rand(1000)}\npublished: true\ntags: heyheyhey,#{tag.name}\n---\n\nHello" + create(:article, title: "My title", user: user2, body_markdown: body_markdown) + end let(:tag) { create(:tag) } let(:mod_user) { create(:user) } - let(:tag_adjustment) { create(:tag_adjustment, user_id: mod_user.id, article_id: article.id, tag_id: tag.id, adjustment_type: "addition") } + let(:tag_adjustment) do + create(:tag_adjustment, user_id: mod_user.id, article_id: article.id, tag_id: tag.id, adjustment_type: "addition") + end let(:notification) { described_class.call(tag_adjustment) } before do diff --git a/spec/services/podcasts/create_episode_spec.rb b/spec/services/podcasts/create_episode_spec.rb index fb0e976fd..2ead8ae40 100644 --- a/spec/services/podcasts/create_episode_spec.rb +++ b/spec/services/podcasts/create_episode_spec.rb @@ -56,7 +56,9 @@ RSpec.describe Podcasts::CreateEpisode, type: :service do context "when item has an http media url" do let(:rss_item) { RSS::Parser.parse("spec/support/fixtures/podcasts/awayfromthekeyboard.rss", false).items.first } let!(:item) { Podcasts::EpisodeRssItem.from_item(rss_item) } - let(:https_url) { "https://awayfromthekeyboard.com/wp-content/uploads/2018/02/Episode_075_Lara_Hogan_Demystifies_Public_Speaking.mp3" } + let(:https_url) do + "https://awayfromthekeyboard.com/wp-content/uploads/2018/02/Episode_075_Lara_Hogan_Demystifies_Public_Speaking.mp3" + end it "sets media_url to https version when it is available" do stub_request(:head, https_url).to_return(status: 200) diff --git a/spec/services/podcasts/episode_rss_item_spec.rb b/spec/services/podcasts/episode_rss_item_spec.rb index 61f649707..bd0f00516 100644 --- a/spec/services/podcasts/episode_rss_item_spec.rb +++ b/spec/services/podcasts/episode_rss_item_spec.rb @@ -2,7 +2,9 @@ require "rails_helper" require "rss" RSpec.describe Podcasts::EpisodeRssItem, type: :service do - let(:enclosure) { instance_double("RSS::Rss::Channel::Item::Enclosure", url: "https://audio.simplecast.com/2330f132.mp3") } + let(:enclosure) do + instance_double("RSS::Rss::Channel::Item::Enclosure", url: "https://audio.simplecast.com/2330f132.mp3") + end let(:guid) { "http://podcast.example/file.mp3" } let(:item) do instance_double("RSS::Rss::Channel::Item", pubDate: "2019-06-19", diff --git a/spec/services/podcasts/feed_spec.rb b/spec/services/podcasts/feed_spec.rb index 2b980159e..a405be114 100644 --- a/spec/services/podcasts/feed_spec.rb +++ b/spec/services/podcasts/feed_spec.rb @@ -27,7 +27,8 @@ RSpec.describe Podcasts::Feed, type: :service, vcr: vcr_option do end it "sets reachable" do - allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", httparty_options).and_raise(Errno::ECONNREFUSED) + allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", + httparty_options).and_raise(Errno::ECONNREFUSED) described_class.new(unpodcast).get_episodes(limit: 2) unpodcast.reload expect(unpodcast.reachable).to be false @@ -35,14 +36,17 @@ RSpec.describe Podcasts::Feed, type: :service, vcr: vcr_option do end it "sets reachable when there redirection is too deep" do - allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", httparty_options).and_raise(HTTParty::RedirectionTooDeep, "too deep") + allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", httparty_options).and_raise( + HTTParty::RedirectionTooDeep, "too deep" + ) described_class.new(unpodcast).get_episodes(limit: 2) unpodcast.reload expect(unpodcast.reachable).to be false end it "schedules the update url jobs when setting as unreachable" do - allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", httparty_options).and_raise(Errno::ECONNREFUSED) + allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", + httparty_options).and_raise(Errno::ECONNREFUSED) create_list(:podcast_episode, 2, podcast: unpodcast) expect do @@ -51,8 +55,10 @@ RSpec.describe Podcasts::Feed, type: :service, vcr: vcr_option do end it "re-checks episodes urls when setting as unreachable" do - allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", httparty_options).and_raise(Errno::ECONNREFUSED) - episode = create(:podcast_episode, podcast: unpodcast, reachable: true, media_url: "http://podcast.example.com/ep1.mp3") + allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", + httparty_options).and_raise(Errno::ECONNREFUSED) + episode = create(:podcast_episode, podcast: unpodcast, reachable: true, + media_url: "http://podcast.example.com/ep1.mp3") allow(HTTParty).to receive(:head).with("http://podcast.example.com/ep1.mp3").and_raise(Errno::ECONNREFUSED) allow(HTTParty).to receive(:head).with("https://podcast.example.com/ep1.mp3").and_raise(Errno::ECONNREFUSED) @@ -66,7 +72,8 @@ RSpec.describe Podcasts::Feed, type: :service, vcr: vcr_option do it "doesn't re-check episodes reachable if the podcast was unreachable" do unpodcast.update_column(:reachable, false) - allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", httparty_options).and_raise(Errno::ECONNREFUSED) + allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", + httparty_options).and_raise(Errno::ECONNREFUSED) create_list(:podcast_episode, 2, podcast: unpodcast) expect do described_class.new(unpodcast).get_episodes(limit: 2) @@ -79,7 +86,8 @@ RSpec.describe Podcasts::Feed, type: :service, vcr: vcr_option do let(:unpodcast) { create(:podcast, feed_url: un_feed_url) } it "sets ssl_failed" do - allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", httparty_options).and_raise(OpenSSL::SSL::SSLError) + allow(HTTParty).to receive(:get).with("http://podcast.example.com/podcast", + httparty_options).and_raise(OpenSSL::SSL::SSLError) described_class.new(unpodcast).get_episodes(limit: 2) unpodcast.reload expect(unpodcast.reachable).to be false @@ -106,14 +114,22 @@ RSpec.describe Podcasts::Feed, type: :service, vcr: vcr_option do described_class.new(podcast).get_episodes(limit: 2) end episodes = podcast.podcast_episodes - expect(episodes.pluck(:title).sort).to eq(["Analyse Asia with Bernard Leong", "IFTTT Architecture with Nicky Leach"]) - expect(episodes.pluck(:media_url).sort).to eq(%w[https://traffic.libsyn.com/sedaily/AnalyseAsia.mp3 https://traffic.libsyn.com/sedaily/IFTTT.mp3]) + expect(episodes.pluck(:title).sort).to eq(["Analyse Asia with Bernard Leong", + "IFTTT Architecture with Nicky Leach"]) + expect(episodes.pluck(:media_url).sort).to eq(%w[https://traffic.libsyn.com/sedaily/AnalyseAsia.mp3 + https://traffic.libsyn.com/sedaily/IFTTT.mp3]) end end context "when updating" do - let!(:episode) { create(:podcast_episode, media_url: "http://traffic.libsyn.com/sedaily/AnalyseAsia.mp3", title: "Old Title", published_at: nil) } - let!(:episode2) { create(:podcast_episode, media_url: "http://traffic.libsyn.com/sedaily/IFTTT.mp3", title: "SuperPodcast", published_at: nil) } + let!(:episode) do + create(:podcast_episode, media_url: "http://traffic.libsyn.com/sedaily/AnalyseAsia.mp3", title: "Old Title", + published_at: nil) + end + let!(:episode2) do + create(:podcast_episode, media_url: "http://traffic.libsyn.com/sedaily/IFTTT.mp3", title: "SuperPodcast", + published_at: nil) + end it "does not refetch already fetched episodes" do expect do diff --git a/spec/services/search/chat_channel_membership_spec.rb b/spec/services/search/chat_channel_membership_spec.rb index 5a6e19257..03905c948 100644 --- a/spec/services/search/chat_channel_membership_spec.rb +++ b/spec/services/search/chat_channel_membership_spec.rb @@ -128,7 +128,8 @@ RSpec.describe Search::ChatChannelMembership, type: :service do chat_channel_membership_docs = described_class.search_documents(params: first_page_params) expect(chat_channel_membership_docs.first["id"]).to eq(chat_channel_membership1.id) - second_page_params = { page: 1, per_page: 1, sort_by: "channel_last_message_at", order: "dsc", user_id: [user.id] } + second_page_params = { page: 1, per_page: 1, sort_by: "channel_last_message_at", order: "dsc", + user_id: [user.id] } chat_channel_membership_docs = described_class.search_documents(params: second_page_params) expect(chat_channel_membership_docs.first["id"]).to eq(chat_channel_membership2.id) diff --git a/spec/services/search/feed_content_spec.rb b/spec/services/search/feed_content_spec.rb index 276ec6192..e5a28a1b9 100644 --- a/spec/services/search/feed_content_spec.rb +++ b/spec/services/search/feed_content_spec.rb @@ -28,7 +28,8 @@ RSpec.describe Search::FeedContent, type: :service do feed_docs = described_class.search_documents(params: query_params) expect(feed_docs.count).to eq(2) doc_highlights = feed_docs.map { |t| t.dig("highlight", "body_text") }.flatten - expect(doc_highlights).to include("I love ruby", "Ruby Tuesday is love") + expect(doc_highlights).to include("I love ruby", + "Ruby Tuesday is love") end it "returns fields necessary for the view" do diff --git a/spec/services/search/query_builders/chat_channel_membership_spec.rb b/spec/services/search/query_builders/chat_channel_membership_spec.rb index 1069f7be0..119835d04 100644 --- a/spec/services/search/query_builders/chat_channel_membership_spec.rb +++ b/spec/services/search/query_builders/chat_channel_membership_spec.rb @@ -46,7 +46,11 @@ RSpec.describe Search::QueryBuilders::ChatChannelMembership, type: :service do "query" => "a_name*", "fields" => [:channel_text], "lenient" => true, "analyze_wildcard" => true } }] - expected_filters = [{ "term" => { "channel_status" => "active" } }, { "terms" => { "status" => %w[active joining_request] } }, { "terms" => { "viewable_by" => 1 } }] + expected_filters = [ + { "term" => { "channel_status" => "active" } }, + { "terms" => { "status" => %w[active joining_request] } }, + { "terms" => { "viewable_by" => 1 } }, + ] expect(query.as_hash.dig("query", "bool", "must")).to match_array(expected_query) expect(query.as_hash.dig("query", "bool", "filter")).to match_array(expected_filters) end diff --git a/spec/services/search/query_builders/feed_content_spec.rb b/spec/services/search/query_builders/feed_content_spec.rb index cc18d2dff..9067eeaa2 100644 --- a/spec/services/search/query_builders/feed_content_spec.rb +++ b/spec/services/search/query_builders/feed_content_spec.rb @@ -72,7 +72,8 @@ RSpec.describe Search::QueryBuilders::FeedContent, type: :service do params = { search_fields: "ruby", published_at: { lte: Time.current }, tag_names: "cfp" } filter = described_class.new(params: params) expected_query = [{ - "simple_query_string" => { "query" => "ruby", "fields" => query_fields, "lenient" => true, "analyze_wildcard" => true, "minimum_should_match" => 2 } + "simple_query_string" => { "query" => "ruby", "fields" => query_fields, "lenient" => true, + "analyze_wildcard" => true, "minimum_should_match" => 2 } }] expected_filters = [ { "range" => { "published_at" => { lte: Time.current } } }, @@ -89,7 +90,8 @@ RSpec.describe Search::QueryBuilders::FeedContent, type: :service do filter = described_class.new(params: params) expected_query = [{ "simple_query_string" => { - "query" => "cfp", "fields" => query_fields, "lenient" => true, "analyze_wildcard" => true, "minimum_should_match" => 2 + "query" => "cfp", "fields" => query_fields, "lenient" => true, + "analyze_wildcard" => true, "minimum_should_match" => 2 } }] expect(search_bool_clause(filter)["must"]).to match_array(expected_query) diff --git a/spec/services/search/query_builders/listing_spec.rb b/spec/services/search/query_builders/listing_spec.rb index 990e3d187..e99b89ecf 100644 --- a/spec/services/search/query_builders/listing_spec.rb +++ b/spec/services/search/query_builders/listing_spec.rb @@ -28,7 +28,8 @@ RSpec.describe Search::QueryBuilders::Listing, type: :service do end it "applies TERM_KEYS from params with boolean mode" do - params = { category: "cfp", tags: %w[beginner intermediate professional], contact_via_connect: false, tag_boolean_mode: "all" } + params = { category: "cfp", tags: %w[beginner intermediate professional], contact_via_connect: false, + tag_boolean_mode: "all" } filter = described_class.new(params: params) expected_filters = [ { "terms" => { "category" => ["cfp"] } }, @@ -73,7 +74,8 @@ RSpec.describe Search::QueryBuilders::Listing, type: :service do params = { classified_listing_search: "test", bumped_at: Time.current, category: "cfp" } filter = described_class.new(params: params) expected_query = [{ - "simple_query_string" => { "query" => "test*", "fields" => [:classified_listing_search], "lenient" => true, "analyze_wildcard" => true } + "simple_query_string" => { "query" => "test*", "fields" => [:classified_listing_search], "lenient" => true, + "analyze_wildcard" => true } }] expected_filters = [ { "range" => { "bumped_at" => Time.current } }, diff --git a/spec/services/search/query_builders/reaction_spec.rb b/spec/services/search/query_builders/reaction_spec.rb index 1c00738ae..0274ce5a1 100644 --- a/spec/services/search/query_builders/reaction_spec.rb +++ b/spec/services/search/query_builders/reaction_spec.rb @@ -54,7 +54,8 @@ RSpec.describe Search::QueryBuilders::Reaction, type: :service do params = { search_fields: "ruby", tag_names: "cfp" } filter = described_class.new(params: params) expected_query = [{ - "simple_query_string" => { "query" => "ruby", "fields" => query_fields, "lenient" => true, "analyze_wildcard" => true, "minimum_should_match" => 2 } + "simple_query_string" => { "query" => "ruby", "fields" => query_fields, "lenient" => true, + "analyze_wildcard" => true, "minimum_should_match" => 2 } }] expected_filters = [ { "terms" => { "reactable.tags.name" => ["cfp"] } }, @@ -70,7 +71,8 @@ RSpec.describe Search::QueryBuilders::Reaction, type: :service do filter = described_class.new(params: params) expected_query = [{ "simple_query_string" => { - "query" => "cfp", "fields" => query_fields, "lenient" => true, "analyze_wildcard" => true, "minimum_should_match" => 2 + "query" => "cfp", "fields" => query_fields, "lenient" => true, + "analyze_wildcard" => true, "minimum_should_match" => 2 } }] expect(search_bool_clause(filter)["must"]).to match_array(expected_query) diff --git a/spec/services/streams/twitch_access_token/get_spec.rb b/spec/services/streams/twitch_access_token/get_spec.rb index 0d1f016a3..1c475c606 100644 --- a/spec/services/streams/twitch_access_token/get_spec.rb +++ b/spec/services/streams/twitch_access_token/get_spec.rb @@ -12,7 +12,8 @@ RSpec.describe Streams::TwitchAccessToken::Get, type: :service do let!(:twitch_token_stubbed_route) do stub_request(:post, "https://id.twitch.tv/oauth2/token"). with(body: expected_twitch_token_body). - and_return(body: { access_token: "FAKE_BRAND_NEW_TWITCH_TOKEN", expires_in: 5_184_000 }.to_json, headers: { "Content-Type" => "application/json" }) + and_return(body: { access_token: "FAKE_BRAND_NEW_TWITCH_TOKEN", + expires_in: 5_184_000 }.to_json, headers: { "Content-Type" => "application/json" }) end before do @@ -24,7 +25,8 @@ RSpec.describe Streams::TwitchAccessToken::Get, type: :service do context "when there is an unexpired token in the cache" do it "returns the cached token" do - Rails.cache.write(described_class::ACCESS_TOKEN_AND_EXPIRATION_CACHE_KEY, ["FAKE_UNEXPIRED_TWITCH_TOKEN", 15.days.from_now]) + Rails.cache.write(described_class::ACCESS_TOKEN_AND_EXPIRATION_CACHE_KEY, + ["FAKE_UNEXPIRED_TWITCH_TOKEN", 15.days.from_now]) expect(described_class.call).to eq "FAKE_UNEXPIRED_TWITCH_TOKEN" expect(twitch_token_stubbed_route).not_to have_been_requested @@ -33,7 +35,8 @@ RSpec.describe Streams::TwitchAccessToken::Get, type: :service do context "when there is an expired token in the cache" do it "requests a new token and caches it" do - Rails.cache.write(described_class::ACCESS_TOKEN_AND_EXPIRATION_CACHE_KEY, ["FAKE_EXPIRED_TWITCH_TOKEN", 15.days.ago]) + Rails.cache.write(described_class::ACCESS_TOKEN_AND_EXPIRATION_CACHE_KEY, + ["FAKE_EXPIRED_TWITCH_TOKEN", 15.days.ago]) expect(described_class.call).to eq "FAKE_BRAND_NEW_TWITCH_TOKEN" expect(twitch_token_stubbed_route).to have_been_requested diff --git a/spec/services/user_blocks/channel_handler_spec.rb b/spec/services/user_blocks/channel_handler_spec.rb index 4d0e5f406..9b1781107 100644 --- a/spec/services/user_blocks/channel_handler_spec.rb +++ b/spec/services/user_blocks/channel_handler_spec.rb @@ -5,7 +5,8 @@ RSpec.describe UserBlocks::ChannelHandler, type: :service do create_list(:user, 2) blocker = User.first blocked = User.second - chat_channel = create(:chat_channel, channel_type: "direct", status: "active", slug: "#{blocker.username}/#{blocked.username}") + chat_channel = create(:chat_channel, channel_type: "direct", status: "active", + slug: "#{blocker.username}/#{blocked.username}") create(:chat_channel_membership, user: blocker, chat_channel: chat_channel) create(:chat_channel_membership, user: blocked, chat_channel: chat_channel) create(:user_block, blocker: blocker, blocked: blocked) diff --git a/spec/services/user_subscriptions/create_from_controller_params_spec.rb b/spec/services/user_subscriptions/create_from_controller_params_spec.rb index 800184c3c..4a16a2bf0 100644 --- a/spec/services/user_subscriptions/create_from_controller_params_spec.rb +++ b/spec/services/user_subscriptions/create_from_controller_params_spec.rb @@ -5,7 +5,8 @@ RSpec.describe UserSubscriptions::CreateFromControllerParams, type: :service do it "returns an error for an invalid source type" do source = create(:comment) - user_subscription_params = { source_type: source.class.name, source_id: source.id, subscriber_email: subscriber.email } + user_subscription_params = { source_type: source.class.name, source_id: source.id, + subscriber_email: subscriber.email } user_subscription = described_class.call(subscriber, user_subscription_params) expect(user_subscription.data).to be_nil @@ -15,7 +16,8 @@ RSpec.describe UserSubscriptions::CreateFromControllerParams, type: :service do it "returns an error for an invalid source" do source = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true) - user_subscription_params = { source_type: source.class.name, source_id: source.id + 999, subscriber_email: subscriber.email } + user_subscription_params = { source_type: source.class.name, source_id: source.id + 999, + subscriber_email: subscriber.email } user_subscription = described_class.call(subscriber, user_subscription_params) expect(user_subscription.data).to be_nil @@ -26,7 +28,8 @@ RSpec.describe UserSubscriptions::CreateFromControllerParams, type: :service do # TODO: [@thepracticaldev/delightful]: re-enable this once email confirmation is re-enabled xit "returns an error for an email mismatch" do source = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true) - user_subscription_params = { source_type: source.class.name, source_id: source.id, subscriber_email: "old@email.com" } + user_subscription_params = { source_type: source.class.name, source_id: source.id, + subscriber_email: "old@email.com" } user_subscription = described_class.call(subscriber, user_subscription_params) expect(user_subscription.data).to be_nil @@ -36,7 +39,8 @@ RSpec.describe UserSubscriptions::CreateFromControllerParams, type: :service do it "returns an error if a UserSubscription can't be created" do source = create(:article, :with_user_subscription_tag_role_user) - user_subscription_params = { source_type: source.class.name, source_id: source.id, subscriber_email: subscriber.email } + user_subscription_params = { source_type: source.class.name, source_id: source.id, + subscriber_email: subscriber.email } user_subscription = described_class.call(subscriber, user_subscription_params) expect(user_subscription.data).to be_nil @@ -46,7 +50,8 @@ RSpec.describe UserSubscriptions::CreateFromControllerParams, type: :service do it "creates a UserSubscription" do source = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true) - user_subscription_params = { source_type: source.class.name, source_id: source.id, subscriber_email: subscriber.email } + user_subscription_params = { source_type: source.class.name, source_id: source.id, + subscriber_email: subscriber.email } user_subscription = described_class.call(subscriber, user_subscription_params) expect(user_subscription.data).to be_an_instance_of UserSubscription diff --git a/spec/services/users/delete_spec.rb b/spec/services/users/delete_spec.rb index 675a48da6..0d188db38 100644 --- a/spec/services/users/delete_spec.rb +++ b/spec/services/users/delete_spec.rb @@ -88,7 +88,8 @@ RSpec.describe Users::Delete, type: :service do end.to change(FieldTest::Membership, :count).by(-1) end - # check that all the associated records are being destroyed, except for those that are kept explicitly (kept_associations) + # check that all the associated records are being destroyed, + # except for those that are kept explicitly (kept_associations) describe "deleting associations" do let(:kept_association_names) do %i[ @@ -96,7 +97,11 @@ RSpec.describe Users::Delete, type: :service do offender_feedback_messages reporter_feedback_messages ] end - let(:direct_associations) { User.reflect_on_all_associations.reject { |a| a.options.key?(:join_table) || a.options.key?(:through) } } + let(:direct_associations) do + User.reflect_on_all_associations.reject do |a| + a.options.key?(:join_table) || a.options.key?(:through) + end + end let!(:user_associations) do create_associations(direct_associations.reject { |a| kept_association_names.include?(a.name) }) end diff --git a/spec/services/users/estimate_default_language_spec.rb b/spec/services/users/estimate_default_language_spec.rb index 7d1a92eaf..5233c8410 100644 --- a/spec/services/users/estimate_default_language_spec.rb +++ b/spec/services/users/estimate_default_language_spec.rb @@ -29,7 +29,8 @@ RSpec.describe Users::EstimateDefaultLanguage, type: :service do it "estimates default language based on identity data dump" do user = create(:user) - create(:identity, provider: :twitter, user: user, auth_data_dump: { "extra" => { "raw_info" => { "lang" => "it" } } }) + create(:identity, provider: :twitter, user: user, + auth_data_dump: { "extra" => { "raw_info" => { "lang" => "it" } } }) described_class.call(user) user.reload expect(user.estimated_default_language).to eq("it") @@ -51,7 +52,8 @@ RSpec.describe Users::EstimateDefaultLanguage, type: :service do it "sets correct language_settings for pt" do user = create(:user) - create(:identity, provider: :twitter, user: user, auth_data_dump: { "extra" => { "raw_info" => { "lang" => "pt" } } }) + create(:identity, provider: :twitter, user: user, + auth_data_dump: { "extra" => { "raw_info" => { "lang" => "pt" } } }) described_class.call(user) user.reload expect(user.language_settings).to eq("preferred_languages" => %w[en pt], "estimated_default_language" => "pt") @@ -65,14 +67,16 @@ RSpec.describe Users::EstimateDefaultLanguage, type: :service do it "doesn't set incorrect language settings" do user = create(:user) - create(:identity, provider: :twitter, user: user, auth_data_dump: { "extra" => { "raw_info" => { "lang" => "supermario" } } }) + create(:identity, provider: :twitter, user: user, + auth_data_dump: { "extra" => { "raw_info" => { "lang" => "supermario" } } }) described_class.call(user) expect(user.language_settings).to eq("preferred_languages" => %w[en], "estimated_default_language" => nil) end it "sets language settings when language is in twitter format (en-gb)" do user = create(:user) - create(:identity, provider: :twitter, user: user, auth_data_dump: { "extra" => { "raw_info" => { "lang" => "en-gb" } } }) + create(:identity, provider: :twitter, user: user, + auth_data_dump: { "extra" => { "raw_info" => { "lang" => "en-gb" } } }) described_class.call(user) expect(user.language_settings).to eq("preferred_languages" => %w[en], "estimated_default_language" => "en") end diff --git a/spec/services/webhook/dispatch_event_spec.rb b/spec/services/webhook/dispatch_event_spec.rb index 1162b80fc..3f0d32941 100644 --- a/spec/services/webhook/dispatch_event_spec.rb +++ b/spec/services/webhook/dispatch_event_spec.rb @@ -12,9 +12,12 @@ RSpec.describe Webhook::DispatchEvent, type: :service do end it "schedules jobs" do - create(:webhook_endpoint, events: %w[article_created], user: user, target_url: "https://create-webhooks.example.com/accept") - create(:webhook_endpoint, events: %w[article_created article_updated article_destroyed], user: user, target_url: "https://all-webhooks.example.com/accept") - create(:webhook_endpoint, events: %w[article_destroyed], user: user, target_url: "https://destroy-webhooks.example.com/accept") + create(:webhook_endpoint, events: %w[article_created], user: user, + target_url: "https://create-webhooks.example.com/accept") + create(:webhook_endpoint, events: %w[article_created article_updated article_destroyed], user: user, + target_url: "https://all-webhooks.example.com/accept") + create(:webhook_endpoint, events: %w[article_destroyed], user: user, + target_url: "https://destroy-webhooks.example.com/accept") sidekiq_assert_enqueued_jobs(2, only: Webhook::DispatchEventWorker) do described_class.call("article_created", article) end @@ -22,7 +25,8 @@ RSpec.describe Webhook::DispatchEvent, type: :service do it "doesn't schedule jobs if the endpoints belong to another user" do user2 = create(:user) - create(:webhook_endpoint, events: %w[article_created], user: user2, target_url: "https://create-webhooks.example.com/accept") + create(:webhook_endpoint, events: %w[article_created], user: user2, + target_url: "https://create-webhooks.example.com/accept") sidekiq_assert_no_enqueued_jobs(only: Webhook::DispatchEventWorker) do described_class.call("article_created", article) end diff --git a/spec/support/api_analytics_shared_examples.rb b/spec/support/api_analytics_shared_examples.rb index 8f4bc7602..b12b10ca7 100644 --- a/spec/support/api_analytics_shared_examples.rb +++ b/spec/support/api_analytics_shared_examples.rb @@ -44,7 +44,8 @@ RSpec.shared_examples "GET /api/analytics/:endpoint authorization examples" do | context "when attempting to view organization analytics without belonging to the organization" do before do - get "/api/analytics/#{endpoint}?organization_id=#{org.id}#{params}", headers: { "api-key" => pro_api_token.secret } + headers = { "api-key" => pro_api_token.secret } + get "/api/analytics/#{endpoint}?organization_id=#{org.id}#{params}", headers: headers end it "renders an error message: 'unauthorized' in JSON" do @@ -70,7 +71,8 @@ RSpec.shared_examples "GET /api/analytics/:endpoint authorization examples" do | context "when attempting to view another organization analytics and not belonging to that organization" do it "responds with status 401 unauthorized" do org = create(:organization) - get "/api/analytics/#{endpoint}?organization_id=#{org.id}#{params}", headers: { "api-key" => org_member_token.secret } + headers = { "api-key" => org_member_token.secret } + get "/api/analytics/#{endpoint}?organization_id=#{org.id}#{params}", headers: headers expect(response).to have_http_status(:unauthorized) end end diff --git a/spec/support/initializers/ci_csv_formatter.rb b/spec/support/initializers/ci_csv_formatter.rb index e4837cfed..cb2aad3e4 100644 --- a/spec/support/initializers/ci_csv_formatter.rb +++ b/spec/support/initializers/ci_csv_formatter.rb @@ -107,6 +107,7 @@ RSpec.configure do |config| backtrace = backtrace.join(" ") if backtrace retry_attempt = ex.metadata[:retry_attempts] - RSpecRetryFormatterHelper.instance.rows << [description, file, status, start_date, start_time, run_time, exception, backtrace, retry_attempt] + RSpecRetryFormatterHelper.instance.rows << [description, file, status, start_date, start_time, run_time, + exception, backtrace, retry_attempt] end end diff --git a/spec/system/articles/user_visits_articles_by_tag_spec.rb b/spec/system/articles/user_visits_articles_by_tag_spec.rb index 29db9092f..02d33d8f6 100644 --- a/spec/system/articles/user_visits_articles_by_tag_spec.rb +++ b/spec/system/articles/user_visits_articles_by_tag_spec.rb @@ -8,7 +8,9 @@ RSpec.describe "User visits articles by tag", type: :system do let(:author) { create(:user, profile_image: nil) } let!(:article) { create(:article, tags: "javascript, IoT", user: author, published_at: 2.days.ago, score: 5) } let!(:article2) { create(:article, tags: "functional", user: author, published_at: Time.current, score: 5) } - let!(:article3) { create(:article, tags: "functional, javascript", user: author, published_at: 2.weeks.ago, score: 5) } + let!(:article3) do + create(:article, tags: "functional, javascript", user: author, published_at: 2.weeks.ago, score: 5) + end context "when user hasn't logged in" do context "when 2 articles" do diff --git a/spec/system/articles/user_visits_articles_by_timeframe_spec.rb b/spec/system/articles/user_visits_articles_by_timeframe_spec.rb index 7c2a56afa..5a6637a17 100644 --- a/spec/system/articles/user_visits_articles_by_timeframe_spec.rb +++ b/spec/system/articles/user_visits_articles_by_timeframe_spec.rb @@ -13,7 +13,8 @@ RSpec.describe "User visits articles by timeframe", type: :system do end def shows_correct_articles_count_via_xpath(count) - expect(page).to have_xpath("//article[contains(@class, 'crayons-story') and contains(@class, 'false')]", count: count) + expect(page).to have_xpath("//article[contains(@class, 'crayons-story') and contains(@class, 'false')]", + count: count) end def shows_main_article diff --git a/spec/system/comments/user_fills_out_comment_spec.rb b/spec/system/comments/user_fills_out_comment_spec.rb index bcf5db337..0196f5d9a 100644 --- a/spec/system/comments/user_fills_out_comment_spec.rb +++ b/spec/system/comments/user_fills_out_comment_spec.rb @@ -122,8 +122,8 @@ RSpec.describe "Creating Comment", type: :system, js: true do it "User attaches an invalid file type" do visit article.path.to_s - allow_only_videos = 'document.querySelector("#image-upload-main").setAttribute("data-permitted-file-types", "[\"video\"]")' - page.execute_script(allow_only_videos) + allow_vids = 'document.querySelector("#image-upload-main").setAttribute("data-permitted-file-types", "[\"video\"]")' + page.execute_script(allow_vids) expect(page).to have_selector('input[data-permitted-file-types="[\"video\"]"]', visible: :hidden) attach_file( @@ -142,8 +142,8 @@ RSpec.describe "Creating Comment", type: :system, js: true do it "User attaches a file with too long of a name" do visit article.path.to_s - limit_file_name_length = 'document.querySelector("#image-upload-main").setAttribute("data-max-file-name-length", "5")' - page.execute_script(limit_file_name_length) + limit_length = 'document.querySelector("#image-upload-main").setAttribute("data-max-file-name-length", "5")' + page.execute_script(limit_length) expect(page).to have_selector('input[data-max-file-name-length="5"]', visible: :hidden) attach_file( diff --git a/spec/system/comments/user_views_article_comments_spec.rb b/spec/system/comments/user_views_article_comments_spec.rb index c14ea93df..82bb2c726 100644 --- a/spec/system/comments/user_views_article_comments_spec.rb +++ b/spec/system/comments/user_views_article_comments_spec.rb @@ -26,7 +26,8 @@ RSpec.describe "Visiting article comments", type: :system, js: true do end it "displays grandchild comments" do - expect(page).to have_selector("#comment-node-#{grandchild_comment.id}.comment-deep-2", visible: :visible, count: 1) + expect(page).to have_selector("#comment-node-#{grandchild_comment.id}.comment-deep-2", visible: :visible, + count: 1) end end @@ -42,7 +43,8 @@ RSpec.describe "Visiting article comments", type: :system, js: true do end it "displays grandchild comments" do - expect(page).to have_selector("#comment-node-#{grandchild_comment.id}.comment-deep-2", visible: :visible, count: 1) + expect(page).to have_selector("#comment-node-#{grandchild_comment.id}.comment-deep-2", visible: :visible, + count: 1) end end end diff --git a/spec/system/dashboards/user_sorts_dashboard_articles_spec.rb b/spec/system/dashboards/user_sorts_dashboard_articles_spec.rb index 1704dac49..c91003afb 100644 --- a/spec/system/dashboards/user_sorts_dashboard_articles_spec.rb +++ b/spec/system/dashboards/user_sorts_dashboard_articles_spec.rb @@ -4,9 +4,18 @@ RSpec.describe "Sorting Dashboard Articles", type: :system, js: true, db_strateg self.use_transactional_tests = false let(:user) { create(:user) } - let(:article1) { create(:article, user_id: user.id, published_at: 10.minutes.ago, created_at: 1.day.ago, public_reactions_count: 5, page_views_count: 0, comments_count: 100) } - let(:article2) { create(:article, user_id: user.id, published_at: 1.minute.ago, created_at: 2.days.ago, public_reactions_count: 1, page_views_count: 10, comments_count: 0) } - let(:article3) { create(:article, user_id: user.id, published_at: 5.minutes.ago, created_at: 3.days.ago, public_reactions_count: 0, page_views_count: 1000, comments_count: 50) } + let(:article1) do + create(:article, user_id: user.id, published_at: 10.minutes.ago, created_at: 1.day.ago, public_reactions_count: 5, + page_views_count: 0, comments_count: 100) + end + let(:article2) do + create(:article, user_id: user.id, published_at: 1.minute.ago, created_at: 2.days.ago, public_reactions_count: 1, + page_views_count: 10, comments_count: 0) + end + let(:article3) do + create(:article, user_id: user.id, published_at: 5.minutes.ago, created_at: 3.days.ago, public_reactions_count: 0, + page_views_count: 1000, comments_count: 50) + end let(:articles) { [article1, article2, article3] } let(:article_with_comments_count_of) do diff --git a/spec/system/internal/admin_manages_reports_spec.rb b/spec/system/internal/admin_manages_reports_spec.rb index 8ec92a0fb..2913b6184 100644 --- a/spec/system/internal/admin_manages_reports_spec.rb +++ b/spec/system/internal/admin_manages_reports_spec.rb @@ -22,9 +22,13 @@ RSpec.describe "Admin manages reports", type: :system do context "when searching for reports" do let(:user) { create(:user) } let(:user2) { create(:user) } - let!(:feedback_message) { create(:feedback_message, :abuse_report, reporter_id: user.id, reported_url: "zzzzzzz999") } + let!(:feedback_message) do + create(:feedback_message, :abuse_report, reporter_id: user.id, reported_url: "zzzzzzz999") + end let!(:feedback_message2) { create(:feedback_message, :abuse_report, reporter_id: user.id, status: "Invalid") } - let!(:feedback_message3) { create(:feedback_message, :abuse_report, reporter_id: user2.id, reported_url: "https://obscure-example-1984.net") } + let!(:feedback_message3) do + create(:feedback_message, :abuse_report, reporter_id: user2.id, reported_url: "https://obscure-example-1984.net") + end before do clear_search_boxes diff --git a/spec/system/user/user_edits_integrations_spec.rb b/spec/system/user/user_edits_integrations_spec.rb index 433d35cc4..f896407b7 100644 --- a/spec/system/user/user_edits_integrations_spec.rb +++ b/spec/system/user/user_edits_integrations_spec.rb @@ -15,7 +15,8 @@ RSpec.describe "User edits their integrations", type: :system, js: true do before do sign_in user - stub_request(:get, "https://api.github.com/user/repos?per_page=100").to_return(status: 200, body: github_response_body.to_json, headers: { "Content-Type" => "application/json" }) + stub_request(:get, "https://api.github.com/user/repos?per_page=100"). + to_return(status: 200, body: github_response_body.to_json, headers: { "Content-Type" => "application/json" }) end describe "via visiting /settings" do diff --git a/spec/workers/rating_votes/assign_rating_worker_spec.rb b/spec/workers/rating_votes/assign_rating_worker_spec.rb index 721edf556..55cbd9767 100644 --- a/spec/workers/rating_votes/assign_rating_worker_spec.rb +++ b/spec/workers/rating_votes/assign_rating_worker_spec.rb @@ -23,7 +23,8 @@ RSpec.describe RatingVotes::AssignRatingWorker, type: :worker do it "assigns implicit readinglist_reaction score" do create(:rating_vote, article_id: article.id, user_id: user.id, rating: 4.0) - create(:rating_vote, article_id: article.id, user_id: second_user.id, rating: 2.0, context: "readinglist_reaction") + create(:rating_vote, article_id: article.id, user_id: second_user.id, rating: 2.0, + context: "readinglist_reaction") worker.perform(article.id) expect(article.reload.experience_level_rating).to eq(3.0) expect(article.reload.experience_level_rating_distribution).to eq(2.0) diff --git a/spec/workers/reactions/bust_reactable_cache_worker_spec.rb b/spec/workers/reactions/bust_reactable_cache_worker_spec.rb index 84099786f..df5c4ffef 100644 --- a/spec/workers/reactions/bust_reactable_cache_worker_spec.rb +++ b/spec/workers/reactions/bust_reactable_cache_worker_spec.rb @@ -22,7 +22,8 @@ RSpec.describe Reactions::BustReactableCacheWorker, type: :worker do it "busts the reactable comment cache" do worker.perform(comment_reaction.id) expect(CacheBuster).to have_received(:bust).with(user.path).once - expect(CacheBuster).to have_received(:bust).with("/reactions?commentable_id=#{article.id}&commentable_type=Article").once + param = "/reactions?commentable_id=#{article.id}&commentable_type=Article" + expect(CacheBuster).to have_received(:bust).with(param).once end it "doesn't fail if a reaction doesn't exist" do