From a6f526b9c4e7e6600852bcc5c7c10f3b11b12084 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Fri, 16 Jun 2023 18:07:53 +0200 Subject: [PATCH 001/590] Update inbox/notification counters when paginating --- app/views/inbox/show.turbo_stream.haml | 12 ++++++++++++ app/views/navigation/_desktop.html.haml | 10 +++------- app/views/navigation/_mobile.html.haml | 7 ++++--- app/views/navigation/icons/_notifications.html.haml | 6 ++++++ app/views/notifications/index.turbo_stream.haml | 3 +++ 5 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 app/views/navigation/icons/_notifications.html.haml diff --git a/app/views/inbox/show.turbo_stream.haml b/app/views/inbox/show.turbo_stream.haml index bbd233bd..e88cfc8d 100644 --- a/app/views/inbox/show.turbo_stream.haml +++ b/app/views/inbox/show.turbo_stream.haml @@ -1,3 +1,5 @@ +- inbox_count = current_user.unread_inbox_count + = turbo_stream.append "entries" do - @inbox.each do |i| = render "inbox/entry", i: @@ -10,3 +12,13 @@ params: { last_id: @inbox_last_id, author: @author }.compact, data: { controller: :hotkey, hotkey: "." }, form: { data: { turbo_stream: true } } + += turbo_stream.update "nav-inbox-desktop" do + = nav_entry t("navigation.inbox"), "/inbox", + badge: inbox_count, badge_attr: { data: { controller: "pwa-badge" } }, + icon: "inbox", hotkey: "g i" + += turbo_stream.update "nav-inbox-mobile" do + = nav_entry t("navigation.inbox"), "/inbox", + badge: inbox_count, badge_color: "primary", badge_pill: true, + icon: "inbox", icon_only: true diff --git a/app/views/navigation/_desktop.html.haml b/app/views/navigation/_desktop.html.haml index 05e9a6a3..167ff830 100644 --- a/app/views/navigation/_desktop.html.haml +++ b/app/views/navigation/_desktop.html.haml @@ -10,7 +10,8 @@ DEV %ul.nav.navbar-nav.me-auto = nav_entry t("navigation.timeline"), root_path, icon: "home", hotkey: "g t" - = nav_entry t("navigation.inbox"), "/inbox", icon: "inbox", badge: inbox_count, badge_attr: { data: { controller: "pwa-badge" } }, hotkey: "g i" + #nav-inbox-desktop + = nav_entry t("navigation.inbox"), "/inbox", icon: "inbox", badge: inbox_count, badge_attr: { data: { controller: "pwa-badge" } }, hotkey: "g i" - if APP_CONFIG.dig(:features, :discover, :enabled) || current_user.mod? = nav_entry t("navigation.discover"), discover_path, icon: "compass", hotkey: "g d" %ul.nav.navbar-nav @@ -23,12 +24,7 @@ %li.nav-item.dropdown.d-none.d-sm-block %a.nav-link.dropdown-toggle{ href: '#', data: { bs_toggle: :dropdown } } %turbo-frame#notification-desktop-icon - - if notification_count.nil? - %i.fa.fa-bell-o - - else - %i.fa.fa-bell - %span.visually-hidden= t("navigation.notifications") - %span.badge= notification_count + = render "navigation/icons/notifications", notification_count: .dropdown-menu.dropdown-menu-end.notification-dropdown %turbo-frame#notifications-dropdown-list - cache current_user.notification_dropdown_cache_key do diff --git a/app/views/navigation/_mobile.html.haml b/app/views/navigation/_mobile.html.haml index 97e37ccc..9c53586d 100644 --- a/app/views/navigation/_mobile.html.haml +++ b/app/views/navigation/_mobile.html.haml @@ -3,9 +3,10 @@ .container %ul.nav.navbar-nav.navbar-icon-row = nav_entry t("navigation.timeline"), root_path, icon: 'home', icon_only: true - = nav_entry t("navigation.inbox"), '/inbox', - badge: inbox_count, badge_color: 'primary', badge_pill: true, - icon: 'inbox', icon_only: true + #nav-inbox-mobile + = nav_entry t("navigation.inbox"), '/inbox', + badge: inbox_count, badge_color: 'primary', badge_pill: true, + icon: 'inbox', icon_only: true - if APP_CONFIG.dig(:features, :discover, :enabled) || current_user.mod? = nav_entry t("navigation.discover"), discover_path, icon: 'compass', icon_only: true = nav_entry t("navigation.notifications"), notifications_path("all"), icon: notifications_icon, diff --git a/app/views/navigation/icons/_notifications.html.haml b/app/views/navigation/icons/_notifications.html.haml new file mode 100644 index 00000000..767ee980 --- /dev/null +++ b/app/views/navigation/icons/_notifications.html.haml @@ -0,0 +1,6 @@ +- if notification_count.nil? + %i.fa.fa-bell-o +- else + %i.fa.fa-bell +%span.visually-hidden= t("navigation.notifications") +%span.badge= notification_count diff --git a/app/views/notifications/index.turbo_stream.haml b/app/views/notifications/index.turbo_stream.haml index 4339faae..378a9a44 100644 --- a/app/views/notifications/index.turbo_stream.haml +++ b/app/views/notifications/index.turbo_stream.haml @@ -13,3 +13,6 @@ params: { last_id: @notifications_last_id }, data: { controller: :hotkey, hotkey: "." }, form: { data: { turbo_stream: true } } + += turbo_stream.update "notification-desktop-icon" do + = render "navigation/icons/notifications", notification_count: current_user.unread_notification_count From 1b05063f4a623c9ab98f54e1ee9ccd95179d26a4 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Fri, 16 Jun 2023 18:09:38 +0200 Subject: [PATCH 002/590] Update tests to check for touching of caching timestamps --- spec/controllers/ajax/answer_controller_spec.rb | 2 ++ spec/controllers/ajax/comment_controller_spec.rb | 15 +++++++++++++++ spec/controllers/inbox_controller_spec.rb | 9 +++------ .../settings/export_controller_spec.rb | 6 ++++-- spec/shared_examples/touches_timestamps.rb | 11 +++++++++++ 5 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 spec/shared_examples/touches_timestamps.rb diff --git a/spec/controllers/ajax/answer_controller_spec.rb b/spec/controllers/ajax/answer_controller_spec.rb index 18c65354..dd2a1ca6 100644 --- a/spec/controllers/ajax/answer_controller_spec.rb +++ b/spec/controllers/ajax/answer_controller_spec.rb @@ -26,6 +26,8 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do end include_examples "returns the expected response" + + include_examples "touches user timestamp", :inbox_updated_at end shared_examples "does not create the answer" do diff --git a/spec/controllers/ajax/comment_controller_spec.rb b/spec/controllers/ajax/comment_controller_spec.rb index 0f4189b8..a93fc126 100644 --- a/spec/controllers/ajax/comment_controller_spec.rb +++ b/spec/controllers/ajax/comment_controller_spec.rb @@ -4,6 +4,8 @@ require "rails_helper" describe Ajax::CommentController, :ajax_controller, type: :controller do + include ActiveSupport::Testing::TimeHelpers + let(:answer) { FactoryBot.create(:answer, user: FactoryBot.create(:user)) } describe "#create" do @@ -23,6 +25,19 @@ describe Ajax::CommentController, :ajax_controller, type: :controller do expect(answer.reload.comments.ids).to include(Comment.last.id) end + context "a user is subscribed to the answer" do + let(:subscribed_user) { FactoryBot.create(:user) } + + it "updates the notification caching timestamp for a subscribed user" do + Subscription.subscribe(subscribed_user, answer) + + travel_to(1.day.from_now) do + expect { subject }.to change { subscribed_user.reload.notifications_updated_at }.to(DateTime.now) + end + end + + end + include_examples "returns the expected response" end diff --git a/spec/controllers/inbox_controller_spec.rb b/spec/controllers/inbox_controller_spec.rb index 94a8accf..a6e5917c 100644 --- a/spec/controllers/inbox_controller_spec.rb +++ b/spec/controllers/inbox_controller_spec.rb @@ -65,12 +65,7 @@ describe InboxController, type: :controller do expect { subject }.to change { inbox_entry.reload.new? }.from(true).to(false) end - it "updates the the timestamp used for caching" do - user.update(inbox_updated_at: original_inbox_updated_at) - travel 1.second do - expect { subject }.to change { user.reload.inbox_updated_at.floor }.from(original_inbox_updated_at.floor).to(Time.now.utc.floor) - end - end + include_examples "touches user timestamp", :inbox_updated_at context "when requested the turbo stream format" do subject { get :show, format: :turbo_stream } @@ -280,6 +275,8 @@ describe InboxController, type: :controller do it "creates an inbox entry" do expect { subject }.to(change { user.inboxes.count }.by(1)) end + + include_examples "touches user timestamp", :inbox_updated_at end end end diff --git a/spec/controllers/settings/export_controller_spec.rb b/spec/controllers/settings/export_controller_spec.rb index 0750ed6e..0bc87796 100644 --- a/spec/controllers/settings/export_controller_spec.rb +++ b/spec/controllers/settings/export_controller_spec.rb @@ -17,18 +17,20 @@ describe Settings::ExportController, type: :controller do end context "when user has a new DataExported notification" do - let(:notification) do + let!(:notification) do Notification::DataExported.create( target_id: user.id, target_type: "User::DataExport", recipient: user, - new: true + new: true, ) end it "marks the notification as read" do expect { subject }.to change { notification.reload.new }.from(true).to(false) end + + include_examples "touches user timestamp", :notifications_updated_at end end end diff --git a/spec/shared_examples/touches_timestamps.rb b/spec/shared_examples/touches_timestamps.rb new file mode 100644 index 00000000..339a1b95 --- /dev/null +++ b/spec/shared_examples/touches_timestamps.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +RSpec.shared_examples_for "touches user timestamp" do |timestamp_column| + include ActiveSupport::Testing::TimeHelpers + + it "touches #{timestamp_column}" do + travel_to(1.day.from_now) do + expect { subject }.to change { user.reload.send(timestamp_column) }.to(DateTime.now) + end + end +end From ece64669a11c6bcca825b80b8fe3fdfcf99c98e3 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Fri, 16 Jun 2023 18:18:40 +0200 Subject: [PATCH 003/590] Update caching timestamps in model events --- app/models/inbox.rb | 12 ++++++++++++ app/models/notification.rb | 16 ++++++++++++++-- app/models/subscription.rb | 7 ++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/app/models/inbox.rb b/app/models/inbox.rb index 6a74687f..1a1a0066 100644 --- a/app/models/inbox.rb +++ b/app/models/inbox.rb @@ -13,6 +13,18 @@ class Inbox < ApplicationRecord !user.privacy_allow_anonymous_questions? end + after_create do + user.touch(:inbox_updated_at) + end + + after_update do + user.touch(:inbox_updated_at) + end + + after_destroy do + user.touch(:inbox_updated_at) + end + def answer(answer_content, user) raise Errors::AnsweringOtherBlockedSelf if question.user&.blocking?(user) raise Errors::AnsweringSelfBlockedOther if user.blocking?(question.user) diff --git a/app/models/notification.rb b/app/models/notification.rb index 3e15eae4..e36cad0a 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -1,9 +1,21 @@ # frozen_string_literal: true class Notification < ApplicationRecord - belongs_to :recipient, class_name: "User", touch: :notifications_updated_at + belongs_to :recipient, class_name: "User" belongs_to :target, polymorphic: true + after_create do + recipient.touch(:notifications_updated_at) + end + + after_update do + recipient.touch(:notifications_updated_at) + end + + after_destroy do + recipient.touch(:notifications_updated_at) + end + class << self include CursorPaginatable @@ -45,7 +57,7 @@ class Notification < ApplicationRecord n = notification_type.new(target:, recipient:, - new: true) + new: true,) n.save! n end diff --git a/app/models/subscription.rb b/app/models/subscription.rb index 0b05a1b9..2e8e7b3c 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -39,7 +39,12 @@ class Subscription < ApplicationRecord { target_id: source.id, target_type: Comment, recipient_id: s.user_id, new: true, type: Notification::Commented, created_at: source.created_at, updated_at: source.created_at } end - Notification.insert_all!(notifications) unless notifications.empty? # rubocop:disable Rails/SkipsModelValidations + return if notifications.empty? + + # rubocop:disable Rails/SkipsModelValidations + Notification.insert_all!(notifications) + User.where(id: notifications.pluck(:recipient_id)).touch_all(:notifications_updated_at) + # rubocop:enable Rails/SkipsModelValidations end def denotify(source, target) From 5a3f65e39abc1c26c36bd92efb84217c9f5a18a6 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Fri, 16 Jun 2023 18:19:31 +0200 Subject: [PATCH 004/590] Ensure counters are up to date when rendering inbox/notifications views --- app/controllers/inbox_controller.rb | 17 ++++++----------- app/controllers/notifications_controller.rb | 7 +++---- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/app/controllers/inbox_controller.rb b/app/controllers/inbox_controller.rb index 661d49f4..7f3db342 100644 --- a/app/controllers/inbox_controller.rb +++ b/app/controllers/inbox_controller.rb @@ -3,8 +3,6 @@ class InboxController < ApplicationController before_action :authenticate_user! - after_action :mark_inbox_entries_as_read, only: %i[show] - def show # rubocop:disable Metrics/MethodLength find_author find_inbox_entries @@ -19,14 +17,11 @@ class InboxController < ApplicationController @delete_id = find_delete_id @disabled = true if @inbox.empty? - respond_to do |format| - format.html { render "show" } - format.turbo_stream do - render "show", layout: false, status: :see_other + mark_inbox_entries_as_read - # rubocop disabled as just flipping a flag doesn't need to have validations to be run - @inbox.update_all(new: false) # rubocop:disable Rails/SkipsModelValidations - end + respond_to do |format| + format.html + format.turbo_stream end end @@ -85,8 +80,8 @@ class InboxController < ApplicationController # rubocop:disable Rails/SkipsModelValidations def mark_inbox_entries_as_read # using .dup to not modify @inbox -- useful in tests - @inbox&.dup&.update_all(new: false) - current_user.touch(:inbox_updated_at) + updated = @inbox&.dup&.update_all(new: false) + current_user.touch(:inbox_updated_at) if updated.positive? end # rubocop:enable Rails/SkipsModelValidations diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index b0088074..a240d3f7 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -3,8 +3,6 @@ class NotificationsController < ApplicationController before_action :authenticate_user! - after_action :mark_notifications_as_read, only: %i[index] - TYPE_MAPPINGS = { "answer" => Notification::QuestionAnswered.name, "comment" => Notification::Commented.name, @@ -18,6 +16,7 @@ class NotificationsController < ApplicationController @notifications = cursored_notifications_for(type: @type, last_id: params[:last_id]) paginate_notifications @counters = count_unread_by_type + mark_notifications_as_read respond_to do |format| format.html @@ -52,8 +51,8 @@ class NotificationsController < ApplicationController # rubocop:disable Rails/SkipsModelValidations def mark_notifications_as_read # using .dup to not modify @notifications -- useful in tests - @notifications&.dup&.update_all(new: false) - current_user.touch(:notifications_updated_at) + updated = @notifications&.dup&.update_all(new: false) + current_user.touch(:notifications_updated_at) if updated.positive? end # rubocop:enable Rails/SkipsModelValidations From bcfb215f8c4b7e21e213f101105f035edd71ea72 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Fri, 16 Jun 2023 18:20:21 +0200 Subject: [PATCH 005/590] Ensure caching timestamp is updated when marking notifications as read --- app/controllers/answer_controller.rb | 3 ++- app/controllers/settings/export_controller.rb | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/controllers/answer_controller.rb b/app/controllers/answer_controller.rb index ac52ab40..2a6e5625 100644 --- a/app/controllers/answer_controller.rb +++ b/app/controllers/answer_controller.rb @@ -51,11 +51,12 @@ class AnswerController < ApplicationController private def mark_notifications_as_read - Notification.where(recipient_id: current_user.id, new: true) + updated = Notification.where(recipient_id: current_user.id, new: true) .and(Notification.where(type: "Notification::QuestionAnswered", target_id: @answer.id) .or(Notification.where(type: "Notification::Commented", target_id: @answer.comments.pluck(:id))) .or(Notification.where(type: "Notification::Smiled", target_id: @answer.smiles.pluck(:id))) .or(Notification.where(type: "Notification::CommentSmiled", target_id: @answer.comment_smiles.pluck(:id)))) .update_all(new: false) # rubocop:disable Rails/SkipsModelValidations + current_user.touch(:notifications_updated_at) if updated.positive? end end diff --git a/app/controllers/settings/export_controller.rb b/app/controllers/settings/export_controller.rb index 1a8bc0a2..3957e427 100644 --- a/app/controllers/settings/export_controller.rb +++ b/app/controllers/settings/export_controller.rb @@ -21,9 +21,12 @@ class Settings::ExportController < ApplicationController private + # rubocop:disable Rails/SkipsModelValidations def mark_notifications_as_read - Notification::DataExported - .where(recipient: current_user, new: true) - .update_all(new: false) # rubocop:disable Rails/SkipsModelValidations + updated = Notification::DataExported + .where(recipient: current_user, new: true) + .update_all(new: false) + current_user.touch(:notifications_updated_at) if updated.positive? end + # rubocop:enable Rails/SkipsModelValidations end From cb89d42813f391eafdf66ae2c3afc7378e7371b8 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Wed, 16 Aug 2023 21:17:18 +0200 Subject: [PATCH 006/590] Put IDs directly on nav entries --- app/helpers/bootstrap_helper.rb | 3 ++- app/views/navigation/_desktop.html.haml | 5 ++--- app/views/navigation/_mobile.html.haml | 7 +++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/helpers/bootstrap_helper.rb b/app/helpers/bootstrap_helper.rb index 4d14e3dc..55544265 100644 --- a/app/helpers/bootstrap_helper.rb +++ b/app/helpers/bootstrap_helper.rb @@ -8,6 +8,7 @@ module BootstrapHelper badge_attr: {}, icon: nil, class: "", + id: nil, hotkey: nil, }.merge(options) @@ -34,7 +35,7 @@ module BootstrapHelper body += " #{content_tag(:span, options[:badge], class: badge_class, **options[:badge_attr])}".html_safe end - content_tag(:li, link_to(body.html_safe, path, class: "nav-link", data: { hotkey: options[:hotkey] }), class: classes) + content_tag(:li, link_to(body.html_safe, path, class: "nav-link", data: { hotkey: options[:hotkey] }), class: classes, id: options[:id]) end def list_group_item(body, path, options = {}) diff --git a/app/views/navigation/_desktop.html.haml b/app/views/navigation/_desktop.html.haml index 167ff830..8efb1151 100644 --- a/app/views/navigation/_desktop.html.haml +++ b/app/views/navigation/_desktop.html.haml @@ -1,4 +1,4 @@ -%nav.navbar.navbar-themed.navbar-expand-lg.bg-primary.fixed-top.d-lg-block.d-none.d-print-none{ class: Rails.env.development? ? "navbar-dev" : "", role: :navigation } +%nav.navbar.navbar-themed.navbar-expand-lg.bg-primary.fixed-top.d-lg-block.d-none.d-print-none{ class: Rails.env.tdevelopment? ? "navbar-dev" : "", role: :navigation } .container %a.navbar-brand{ href: '/', title: APP_CONFIG["site_name"] } - if APP_CONFIG["use_svg_logo"] @@ -10,8 +10,7 @@ DEV %ul.nav.navbar-nav.me-auto = nav_entry t("navigation.timeline"), root_path, icon: "home", hotkey: "g t" - #nav-inbox-desktop - = nav_entry t("navigation.inbox"), "/inbox", icon: "inbox", badge: inbox_count, badge_attr: { data: { controller: "pwa-badge" } }, hotkey: "g i" + = nav_entry t("navigation.inbox"), "/inbox", icon: "inbox", badge: inbox_count, badge_attr: { data: { controller: "pwa-badge" } }, hotkey: "g i", id: "nav-inbox-desktop" - if APP_CONFIG.dig(:features, :discover, :enabled) || current_user.mod? = nav_entry t("navigation.discover"), discover_path, icon: "compass", hotkey: "g d" %ul.nav.navbar-nav diff --git a/app/views/navigation/_mobile.html.haml b/app/views/navigation/_mobile.html.haml index 9c53586d..2b68f081 100644 --- a/app/views/navigation/_mobile.html.haml +++ b/app/views/navigation/_mobile.html.haml @@ -3,10 +3,9 @@ .container %ul.nav.navbar-nav.navbar-icon-row = nav_entry t("navigation.timeline"), root_path, icon: 'home', icon_only: true - #nav-inbox-mobile - = nav_entry t("navigation.inbox"), '/inbox', - badge: inbox_count, badge_color: 'primary', badge_pill: true, - icon: 'inbox', icon_only: true + = nav_entry t("navigation.inbox"), '/inbox', + badge: inbox_count, badge_color: 'primary', badge_pill: true, + icon: 'inbox', icon_only: true, id: "nav-inbox-mobile" - if APP_CONFIG.dig(:features, :discover, :enabled) || current_user.mod? = nav_entry t("navigation.discover"), discover_path, icon: 'compass', icon_only: true = nav_entry t("navigation.notifications"), notifications_path("all"), icon: notifications_icon, From eed4ed5d4bd5147a5df68d4d092e3006ac0ff900 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Wed, 16 Aug 2023 21:19:05 +0200 Subject: [PATCH 007/590] Add test for putting IDs on nav entries --- spec/helpers/bootstrap_helper_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/helpers/bootstrap_helper_spec.rb b/spec/helpers/bootstrap_helper_spec.rb index b996f162..4cacecd7 100644 --- a/spec/helpers/bootstrap_helper_spec.rb +++ b/spec/helpers/bootstrap_helper_spec.rb @@ -42,6 +42,13 @@ describe BootstrapHelper, :type => :helper do eq('') ) end + + it 'should put an ID on the entry an id if given' do + allow(self).to receive(:current_page?).and_return(false) + expect(nav_entry('Example', '/example', id: "testing")).to( + eq('') + ) + end end describe "#list_group_item" do From 54ac832c9195c90393d3ac13758e4bb8bc720460 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Wed, 16 Aug 2023 21:57:31 +0200 Subject: [PATCH 008/590] Ensure inbox caching timestamp gets updated when answering questions and returning to inbox --- app/models/answer.rb | 1 + spec/controllers/ajax/answer_controller_spec.rb | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/app/models/answer.rb b/app/models/answer.rb index 5e43464b..71417252 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -20,6 +20,7 @@ class Answer < ApplicationRecord after_create do Inbox.where(user: self.user, question: self.question).destroy_all + user.touch :inbox_updated_at # rubocop:disable Rails/SkipsModelValidations Notification.notify self.question.user, self unless self.question.user == self.user or self.question.user.nil? Subscription.subscribe self.user, self diff --git a/spec/controllers/ajax/answer_controller_spec.rb b/spec/controllers/ajax/answer_controller_spec.rb index dd2a1ca6..3e42c2e7 100644 --- a/spec/controllers/ajax/answer_controller_spec.rb +++ b/spec/controllers/ajax/answer_controller_spec.rb @@ -4,6 +4,8 @@ require "rails_helper" describe Ajax::AnswerController, :ajax_controller, type: :controller do + include ActiveSupport::Testing::TimeHelpers + let(:question) { FactoryBot.create(:question, user: FactoryBot.build(:user, privacy_allow_stranger_answers: asker_allows_strangers)) } let(:asker_allows_strangers) { true } @@ -327,6 +329,14 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do user.save expect { subject }.to(change { Inbox.where(question_id: answer.question.id, user_id: user.id).count }.by(1)) end + + it "updates the inbox caching timestamp for the user who answered" do + initial_timestamp = 1.day.ago + answer.user.update(inbox_updated_at: initial_timestamp) + freeze_time do + expect { subject }.to(change { answer.user.reload.inbox_updated_at }.from(initial_timestamp).to(DateTime.now)) + end + end end context "when the answer exists and was not made by the current user" do From a5c58da48c257d2c57cdb8b8d5506f98ad044724 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Thu, 17 Aug 2023 20:54:37 +0200 Subject: [PATCH 009/590] Set time explicitly --- spec/controllers/ajax/answer_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/ajax/answer_controller_spec.rb b/spec/controllers/ajax/answer_controller_spec.rb index 3e42c2e7..1f1632f2 100644 --- a/spec/controllers/ajax/answer_controller_spec.rb +++ b/spec/controllers/ajax/answer_controller_spec.rb @@ -333,7 +333,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do it "updates the inbox caching timestamp for the user who answered" do initial_timestamp = 1.day.ago answer.user.update(inbox_updated_at: initial_timestamp) - freeze_time do + travel_to 1.day.from_now do expect { subject }.to(change { answer.user.reload.inbox_updated_at }.from(initial_timestamp).to(DateTime.now)) end end From efb9b032951115b8fb2e8e84ce4f006509850d6f Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Fri, 18 Aug 2023 18:22:45 +0200 Subject: [PATCH 010/590] Compare time using string representation --- spec/controllers/ajax/answer_controller_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/controllers/ajax/answer_controller_spec.rb b/spec/controllers/ajax/answer_controller_spec.rb index 1f1632f2..2a8906ca 100644 --- a/spec/controllers/ajax/answer_controller_spec.rb +++ b/spec/controllers/ajax/answer_controller_spec.rb @@ -334,7 +334,8 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do initial_timestamp = 1.day.ago answer.user.update(inbox_updated_at: initial_timestamp) travel_to 1.day.from_now do - expect { subject }.to(change { answer.user.reload.inbox_updated_at }.from(initial_timestamp).to(DateTime.now)) + # using string representation to avoid precision issues + expect { subject }.to(change { answer.user.reload.inbox_updated_at.to_s }.from(initial_timestamp.to_s).to(DateTime.now)) end end end From 620121341e9aa313693298d1d1167927cf1012fd Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Fri, 18 Aug 2023 19:41:21 +0200 Subject: [PATCH 011/590] Fix typo --- app/views/navigation/_desktop.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/navigation/_desktop.html.haml b/app/views/navigation/_desktop.html.haml index 8efb1151..fc0cce38 100644 --- a/app/views/navigation/_desktop.html.haml +++ b/app/views/navigation/_desktop.html.haml @@ -1,4 +1,4 @@ -%nav.navbar.navbar-themed.navbar-expand-lg.bg-primary.fixed-top.d-lg-block.d-none.d-print-none{ class: Rails.env.tdevelopment? ? "navbar-dev" : "", role: :navigation } +%nav.navbar.navbar-themed.navbar-expand-lg.bg-primary.fixed-top.d-lg-block.d-none.d-print-none{ class: Rails.env.development? ? "navbar-dev" : "", role: :navigation } .container %a.navbar-brand{ href: '/', title: APP_CONFIG["site_name"] } - if APP_CONFIG["use_svg_logo"] From d39f37072d76614e603433694375a8abd0d8402e Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Fri, 18 Aug 2023 19:43:59 +0200 Subject: [PATCH 012/590] Fix lint errors --- app/models/subscription.rb | 25 +++++++++++++------ .../ajax/comment_controller_spec.rb | 1 - spec/helpers/bootstrap_helper_spec.rb | 6 ++--- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/models/subscription.rb b/app/models/subscription.rb index 2e8e7b3c..2274fcac 100644 --- a/app/models/subscription.rb +++ b/app/models/subscription.rb @@ -28,15 +28,18 @@ class Subscription < ApplicationRecord def notify(source, target) return nil if source.nil? || target.nil? - muted_by = Relationships::Mute.where(target: source.user).pluck(&:source_id) - # As we will need to notify for each person subscribed, # it's much faster to bulk insert than to use +Notification.notify+ - notifications = Subscription.where(answer: target) - .where.not(user: source.user) - .where.not(user_id: muted_by) - .map do |s| - { target_id: source.id, target_type: Comment, recipient_id: s.user_id, new: true, type: Notification::Commented, created_at: source.created_at, updated_at: source.created_at } + notifications = Subscription.for(source, target).pluck(:user_id).map do |recipient_id| + { + target_id: source.id, + target_type: Comment, + recipient_id:, + new: true, + type: Notification::Commented, + created_at: source.created_at, + updated_at: source.created_at, + } end return if notifications.empty? @@ -53,5 +56,13 @@ class Subscription < ApplicationRecord subs = Subscription.where(answer: target) Notification.where(target:, recipient: subs.map(&:user)).delete_all end + + def for(source, target) + muted_by = Relationships::Mute.where(target: source.user).pluck(&:source_id) + + Subscription.where(answer: target) + .where.not(user: source.user) + .where.not(user_id: muted_by) + end end end diff --git a/spec/controllers/ajax/comment_controller_spec.rb b/spec/controllers/ajax/comment_controller_spec.rb index a93fc126..ace88ce6 100644 --- a/spec/controllers/ajax/comment_controller_spec.rb +++ b/spec/controllers/ajax/comment_controller_spec.rb @@ -35,7 +35,6 @@ describe Ajax::CommentController, :ajax_controller, type: :controller do expect { subject }.to change { subscribed_user.reload.notifications_updated_at }.to(DateTime.now) end end - end include_examples "returns the expected response" diff --git a/spec/helpers/bootstrap_helper_spec.rb b/spec/helpers/bootstrap_helper_spec.rb index 4cacecd7..0f31f85e 100644 --- a/spec/helpers/bootstrap_helper_spec.rb +++ b/spec/helpers/bootstrap_helper_spec.rb @@ -43,10 +43,10 @@ describe BootstrapHelper, :type => :helper do ) end - it 'should put an ID on the entry an id if given' do + it "should put an ID on the entry an id if given" do allow(self).to receive(:current_page?).and_return(false) - expect(nav_entry('Example', '/example', id: "testing")).to( - eq('') + expect(nav_entry("Example", "/example", id: "testing")).to( + eq("
  • Example
  • "), ) end end From dc355d1dd28c9ad993ab3bd37f69eb16dbd08afd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:12:14 +0000 Subject: [PATCH 013/590] Bump sass from 1.66.1 to 1.67.0 Bumps [sass](https://github.com/sass/dart-sass) from 1.66.1 to 1.67.0. - [Release notes](https://github.com/sass/dart-sass/releases) - [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md) - [Commits](https://github.com/sass/dart-sass/compare/1.66.1...1.67.0) --- updated-dependencies: - dependency-name: sass dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 49f471aa..3931e773 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "croppr": "^2.3.1", "i18n-js": "^4.0", "js-cookie": "2.2.1", - "sass": "^1.66.1", + "sass": "^1.67.0", "sweetalert": "1.1.3", "toastify-js": "^1.12.0", "typescript": "^5.2.2" diff --git a/yarn.lock b/yarn.lock index 83cc6805..4ee4f418 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2268,10 +2268,10 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -sass@^1.66.1: - version "1.66.1" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.66.1.tgz#04b51c4671e4650aa393740e66a4e58b44d055b1" - integrity sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA== +sass@^1.67.0: + version "1.67.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.67.0.tgz#fed84d74b9cd708db603b1380d6dc1f71bb24f6f" + integrity sha512-SVrO9ZeX/QQyEGtuZYCVxoeAL5vGlYjJ9p4i4HFuekWl8y/LtJ7tJc10Z+ck1c8xOuoBm2MYzcLfTAffD0pl/A== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" From 884505a311e1f4d0fbaf01aa39e3e7e8852f6fd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:12:25 +0000 Subject: [PATCH 014/590] Bump stylelint-scss from 5.1.0 to 5.2.1 Bumps [stylelint-scss](https://github.com/stylelint-scss/stylelint-scss) from 5.1.0 to 5.2.1. - [Release notes](https://github.com/stylelint-scss/stylelint-scss/releases) - [Changelog](https://github.com/stylelint-scss/stylelint-scss/blob/master/CHANGELOG.md) - [Commits](https://github.com/stylelint-scss/stylelint-scss/compare/v5.1.0...v5.2.1) --- updated-dependencies: - dependency-name: stylelint-scss dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 49f471aa..24b91576 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,6 @@ "eslint-plugin-import": "^2.28.1", "stylelint": "^15.10.3", "stylelint-config-standard-scss": "^11.0.0", - "stylelint-scss": "^5.1.0" + "stylelint-scss": "^5.2.1" } } diff --git a/yarn.lock b/yarn.lock index 83cc6805..7115a590 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2475,11 +2475,12 @@ stylelint-config-standard@^34.0.0: dependencies: stylelint-config-recommended "^13.0.0" -stylelint-scss@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-5.1.0.tgz#dd318bc5c65f7a11f3ecacc7b6e8b67e7f2f1df1" - integrity sha512-E+KlQFXv1Euha43qw3q+wKBSli557wxbbo6/39DWhRNXlUa9Cz+FYrcgz+PT6ag0l6UisCYjAGCNhoSl4FcwlA== +stylelint-scss@^5.1.0, stylelint-scss@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-5.2.1.tgz#810299e4141fa38852bd14536a90e4942c8f387f" + integrity sha512-ZoTJUM85/qqpQHfEppjW/St//8s6p9Qsg8deWlYlr56F9iUgC9vXeIDQvH4odkRRJLTLFQzYMALSOFCQ3MDkgw== dependencies: + known-css-properties "^0.28.0" postcss-media-query-parser "^0.2.3" postcss-resolve-nested-selector "^0.1.1" postcss-selector-parser "^6.0.13" From 223cfc189053129ebb42ecf2ff559f455bceaa85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:14:49 +0000 Subject: [PATCH 015/590] Bump docker/build-push-action from 4 to 5 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v4...v5) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml index 36b98fa1..895123df 100644 --- a/.github/workflows/build-image.yml +++ b/.github/workflows/build-image.yml @@ -46,7 +46,7 @@ jobs: if: github.event_name != 'pull_request' - name: Build and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: build-args: | BUNDLER_VERSION=${{ env.BUNDLER_VERSION }} From 829ed00955ae929215c4b7284378f838e9ec6131 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:14:53 +0000 Subject: [PATCH 016/590] Bump docker/login-action from 2 to 3 Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v2...v3) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml index 36b98fa1..a4b0b57d 100644 --- a/.github/workflows/build-image.yml +++ b/.github/workflows/build-image.yml @@ -38,7 +38,7 @@ jobs: esac - name: Login to registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} From a997696570450e49fac2fe2230e43b7b806d0e20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:53:34 +0000 Subject: [PATCH 017/590] Bump cssbundling-rails from 1.2.0 to 1.3.2 Bumps [cssbundling-rails](https://github.com/rails/cssbundling-rails) from 1.2.0 to 1.3.2. - [Release notes](https://github.com/rails/cssbundling-rails/releases) - [Commits](https://github.com/rails/cssbundling-rails/compare/v1.2.0...v1.3.2) --- updated-dependencies: - dependency-name: cssbundling-rails dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 4d6b3573..da35a354 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ gem "i18n-js", "4.0" gem "rails", "~> 6.1" gem "rails-i18n", "~> 7.0" -gem "cssbundling-rails", "~> 1.2" +gem "cssbundling-rails", "~> 1.3" gem "jsbundling-rails", "~> 1.1" gem "sassc-rails" gem "sprockets", "~> 4.2" diff --git a/Gemfile.lock b/Gemfile.lock index 1293ed02..d5c87a8d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -107,7 +107,7 @@ GEM concurrent-ruby (1.2.2) connection_pool (2.4.1) crass (1.0.6) - cssbundling-rails (1.2.0) + cssbundling-rails (1.3.2) railties (>= 6.0.0) database_cleaner (2.0.2) database_cleaner-active_record (>= 2, < 3) @@ -504,7 +504,7 @@ DEPENDENCIES carrierwave_backgrounder! colorize connection_pool - cssbundling-rails (~> 1.2) + cssbundling-rails (~> 1.3) database_cleaner devise (~> 4.9) devise-async From 0d7c2316a72966dffc0ec8f4ee5f9b1983cabfc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:54:20 +0000 Subject: [PATCH 018/590] Bump rubocop-rails from 2.21.0 to 2.21.1 Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.21.0 to 2.21.1. - [Release notes](https://github.com/rubocop/rubocop-rails/releases) - [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.21.0...v2.21.1) --- updated-dependencies: - dependency-name: rubocop-rails dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1293ed02..18c6668e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -404,7 +404,7 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.29.0) parser (>= 3.2.1.0) - rubocop-rails (2.21.0) + rubocop-rails (2.21.1) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) From b1fa1083db80df75f5b088000b1be35fe8134533 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:55:18 +0000 Subject: [PATCH 019/590] Bump sanitize from 6.0.2 to 6.1.0 Bumps [sanitize](https://github.com/rgrove/sanitize) from 6.0.2 to 6.1.0. - [Release notes](https://github.com/rgrove/sanitize/releases) - [Changelog](https://github.com/rgrove/sanitize/blob/main/HISTORY.md) - [Commits](https://github.com/rgrove/sanitize/compare/v6.0.2...v6.1.0) --- updated-dependencies: - dependency-name: sanitize dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1293ed02..f794762f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -412,7 +412,7 @@ GEM ruby-vips (2.1.4) ffi (~> 1.12) rubyzip (2.3.2) - sanitize (6.0.2) + sanitize (6.1.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) sassc (2.4.0) From adc994f658cf95d8a08c158303e71b32f3a044ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 15:42:24 +0000 Subject: [PATCH 020/590] Bump jsbundling-rails from 1.1.2 to 1.2.1 Bumps [jsbundling-rails](https://github.com/rails/jsbundling-rails) from 1.1.2 to 1.2.1. - [Release notes](https://github.com/rails/jsbundling-rails/releases) - [Commits](https://github.com/rails/jsbundling-rails/compare/v1.1.2...v1.2.1) --- updated-dependencies: - dependency-name: jsbundling-rails dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index da35a354..08789eae 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gem "rails", "~> 6.1" gem "rails-i18n", "~> 7.0" gem "cssbundling-rails", "~> 1.3" -gem "jsbundling-rails", "~> 1.1" +gem "jsbundling-rails", "~> 1.2" gem "sassc-rails" gem "sprockets", "~> 4.2" gem "sprockets-rails", require: "sprockets/railtie" diff --git a/Gemfile.lock b/Gemfile.lock index d5c87a8d..6c151c5b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -209,7 +209,7 @@ GEM image_processing (1.12.2) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) - jsbundling-rails (1.1.2) + jsbundling-rails (1.2.1) railties (>= 6.0.0) json (2.6.3) json-schema (4.0.0) @@ -523,7 +523,7 @@ DEPENDENCIES hcaptcha (~> 7.0) httparty i18n-js (= 4.0) - jsbundling-rails (~> 1.1) + jsbundling-rails (~> 1.2) json-schema jwt (~> 2.7) letter_opener From cd5a885f9ed6156efcddaa0d963e549f011671c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 15:47:17 +0000 Subject: [PATCH 021/590] Bump json-schema from 4.0.0 to 4.1.1 Bumps [json-schema](https://github.com/voxpupuli/json-schema) from 4.0.0 to 4.1.1. - [Changelog](https://github.com/voxpupuli/json-schema/blob/master/CHANGELOG.md) - [Commits](https://github.com/voxpupuli/json-schema/compare/v4.0.0...v4.1.1) --- updated-dependencies: - dependency-name: json-schema dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 6c151c5b..22f083d3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,7 +75,7 @@ GEM minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.4) + addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) base64 (0.1.1) @@ -212,7 +212,7 @@ GEM jsbundling-rails (1.2.1) railties (>= 6.0.0) json (2.6.3) - json-schema (4.0.0) + json-schema (4.1.1) addressable (>= 2.8) jwt (2.7.1) kaminari (1.2.2) @@ -286,7 +286,7 @@ GEM pghero (3.3.4) activerecord (>= 6) prometheus-client (4.2.1) - public_suffix (5.0.1) + public_suffix (5.0.3) puma (6.3.1) nio4r (~> 2.0) pundit (2.3.1) From 8fad702d9b3441101c9c638be085a4e0138bd6f8 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Fri, 22 Sep 2023 18:31:05 +0200 Subject: [PATCH 022/590] Ignore carrierwave_backgrounder in Dependabot It slips into a sentry-related update PR, and it won't update anyway since it's a fork from us. --- .github/dependabot.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0d514c8e..809c1178 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -18,6 +18,8 @@ updates: schedule: interval: weekly open-pull-requests-limit: 99 + ignore: + - dependency-name: 'carrierwave_backgrounder' allow: - dependency-type: direct @@ -27,4 +29,4 @@ updates: interval: weekly open-pull-requests-limit: 99 allow: - - dependency-type: direct \ No newline at end of file + - dependency-type: direct From 57b7c9666040f8271cec5adf91adc865716c9330 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 17:05:21 +0000 Subject: [PATCH 023/590] Bump net-smtp from 0.3.3 to 0.4.0 Bumps [net-smtp](https://github.com/ruby/net-smtp) from 0.3.3 to 0.4.0. - [Release notes](https://github.com/ruby/net-smtp/releases) - [Changelog](https://github.com/ruby/net-smtp/blob/master/NEWS.md) - [Commits](https://github.com/ruby/net-smtp/compare/v0.3.3...v0.4.0) --- updated-dependencies: - dependency-name: net-smtp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8ea97f4c..7f75fd48 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -269,7 +269,7 @@ GEM net-protocol net-protocol (0.2.1) timeout - net-smtp (0.3.3) + net-smtp (0.4.0) net-protocol nio4r (2.5.9) nokogiri (1.15.4) From bf315baa6aefdda2b198a5a7e054135a84ed0f06 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 17:06:03 +0000 Subject: [PATCH 024/590] Bump openssl from 3.1.0 to 3.2.0 Bumps [openssl](https://github.com/ruby/openssl) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/ruby/openssl/releases) - [Changelog](https://github.com/ruby/openssl/blob/master/History.md) - [Commits](https://github.com/ruby/openssl/compare/v3.1.0...v3.2.0) --- updated-dependencies: - dependency-name: openssl dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 08789eae..dac7c564 100644 --- a/Gemfile +++ b/Gemfile @@ -112,7 +112,7 @@ gem "pundit", "~> 2.3" gem "rubyzip", "~> 2.3" # to solve https://github.com/jwt/ruby-jwt/issues/526 -gem "openssl", "~> 3.1" +gem "openssl", "~> 3.2" # mail 2.8.0 breaks sendmail usage: https://github.com/mikel/mail/issues/1538 gem "mail", "~> 2.7.1" diff --git a/Gemfile.lock b/Gemfile.lock index 8ea97f4c..09926e74 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -276,7 +276,7 @@ GEM mini_portile2 (~> 2.8.2) racc (~> 1.4) oj (3.16.1) - openssl (3.1.0) + openssl (3.2.0) orm_adapter (0.5.0) parallel (1.23.0) parser (3.2.2.3) @@ -534,7 +534,7 @@ DEPENDENCIES net-pop net-smtp oj - openssl (~> 3.1) + openssl (~> 3.2) pg pghero prometheus-client (~> 4.2) From b78e9cf4c061ca966f775185251e3c23ec1be854 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 17:06:45 +0000 Subject: [PATCH 025/590] Bump cssbundling-rails from 1.3.2 to 1.3.3 Bumps [cssbundling-rails](https://github.com/rails/cssbundling-rails) from 1.3.2 to 1.3.3. - [Release notes](https://github.com/rails/cssbundling-rails/releases) - [Commits](https://github.com/rails/cssbundling-rails/compare/v1.3.2...v1.3.3) --- updated-dependencies: - dependency-name: cssbundling-rails dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8ea97f4c..36e6f89b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -107,7 +107,7 @@ GEM concurrent-ruby (1.2.2) connection_pool (2.4.1) crass (1.0.6) - cssbundling-rails (1.3.2) + cssbundling-rails (1.3.3) railties (>= 6.0.0) database_cleaner (2.0.2) database_cleaner-active_record (>= 2, < 3) From 79fb904db02e1c78baa618e76e4daf09b4b5c62a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 17:06:59 +0000 Subject: [PATCH 026/590] Bump puma from 6.3.1 to 6.4.0 Bumps [puma](https://github.com/puma/puma) from 6.3.1 to 6.4.0. - [Release notes](https://github.com/puma/puma/releases) - [Changelog](https://github.com/puma/puma/blob/master/History.md) - [Commits](https://github.com/puma/puma/compare/v6.3.1...v6.4.0) --- updated-dependencies: - dependency-name: puma dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8ea97f4c..fd0d7ca5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -287,7 +287,7 @@ GEM activerecord (>= 6) prometheus-client (4.2.1) public_suffix (5.0.3) - puma (6.3.1) + puma (6.4.0) nio4r (~> 2.0) pundit (2.3.1) activesupport (>= 3.0.0) From 66219ee433e5ca5314a877bd0f473fa32659e764 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 17:16:11 +0000 Subject: [PATCH 027/590] Bump sass from 1.67.0 to 1.68.0 Bumps [sass](https://github.com/sass/dart-sass) from 1.67.0 to 1.68.0. - [Release notes](https://github.com/sass/dart-sass/releases) - [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md) - [Commits](https://github.com/sass/dart-sass/compare/1.67.0...1.68.0) --- updated-dependencies: - dependency-name: sass dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 47e52286..17eefbca 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "croppr": "^2.3.1", "i18n-js": "^4.0", "js-cookie": "2.2.1", - "sass": "^1.67.0", + "sass": "^1.68.0", "sweetalert": "1.1.3", "toastify-js": "^1.12.0", "typescript": "^5.2.2" diff --git a/yarn.lock b/yarn.lock index 4a677035..ba1d0abb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2268,10 +2268,10 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -sass@^1.67.0: - version "1.67.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.67.0.tgz#fed84d74b9cd708db603b1380d6dc1f71bb24f6f" - integrity sha512-SVrO9ZeX/QQyEGtuZYCVxoeAL5vGlYjJ9p4i4HFuekWl8y/LtJ7tJc10Z+ck1c8xOuoBm2MYzcLfTAffD0pl/A== +sass@^1.68.0: + version "1.68.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.68.0.tgz#0034b0cc9a50248b7d1702ac166fd25990023669" + integrity sha512-Lmj9lM/fef0nQswm1J2HJcEsBUba4wgNx2fea6yJHODREoMFnwRpZydBnX/RjyXw2REIwdkbqE4hrTo4qfDBUA== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" From f99e4dc1d8ce2933c85ca17357188c43c60ccddf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 09:37:54 +0000 Subject: [PATCH 028/590] Bump actions/checkout from 4.0.0 to 4.1.0 Bumps [actions/checkout](https://github.com/actions/checkout) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.0.0...v4.1.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build-image.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/lint.yml | 8 ++++---- .github/workflows/retrospring.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml index f3048f8d..88760a4d 100644 --- a/.github/workflows/build-image.yml +++ b/.github/workflows/build-image.yml @@ -20,7 +20,7 @@ jobs: cancel-in-progress: true steps: - - uses: actions/checkout@v4.0.0 + - uses: actions/checkout@v4.1.0 - name: Discover build-time variables run: | diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index da1c33c7..a28d196c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -33,7 +33,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4.0.0 + uses: actions/checkout@v4.1.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 27e57015..237b9882 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,7 +11,7 @@ jobs: name: Rubocop runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.0.0 + - uses: actions/checkout@v4.1.0 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v39 @@ -37,7 +37,7 @@ jobs: name: ESLint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.0.0 + - uses: actions/checkout@v4.1.0 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v39 @@ -63,7 +63,7 @@ jobs: haml-lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.0.0 + - uses: actions/checkout@v4.1.0 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v39 @@ -86,7 +86,7 @@ jobs: stylelint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.0.0 + - uses: actions/checkout@v4.1.0 - name: Get changed files id: changed-files uses: tj-actions/changed-files@v39 diff --git a/.github/workflows/retrospring.yml b/.github/workflows/retrospring.yml index fefbfc04..e46aeeaa 100644 --- a/.github/workflows/retrospring.yml +++ b/.github/workflows/retrospring.yml @@ -41,7 +41,7 @@ jobs: BUNDLE_WITHOUT: 'production' steps: - - uses: actions/checkout@v4.0.0 + - uses: actions/checkout@v4.1.0 - name: Install dependencies run: sudo apt update && sudo apt-get install -y libpq-dev libxml2-dev libxslt1-dev libmagickwand-dev imagemagick libidn11-dev - name: Set up Ruby From 9bf56e463bd2dabfe26c9e9b368ebdce8452d3d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 09:21:24 +0000 Subject: [PATCH 029/590] Bump rubocop-rails from 2.21.1 to 2.21.2 Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.21.1 to 2.21.2. - [Release notes](https://github.com/rubocop/rubocop-rails/releases) - [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.21.1...v2.21.2) --- updated-dependencies: - dependency-name: rubocop-rails dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9485d52c..7028c97e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -404,7 +404,7 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.29.0) parser (>= 3.2.1.0) - rubocop-rails (2.21.1) + rubocop-rails (2.21.2) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) @@ -477,7 +477,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.8) - unicode-display_width (2.4.2) + unicode-display_width (2.5.0) uniform_notifier (1.16.0) warden (1.2.9) rack (>= 2.0.9) @@ -487,7 +487,7 @@ GEM websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - zeitwerk (2.6.11) + zeitwerk (2.6.12) PLATFORMS ruby From 12ca8e5efea4dc12de2c009f9075185734c1f085 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 09:22:21 +0000 Subject: [PATCH 030/590] Bump rubocop from 1.56.3 to 1.56.4 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.3 to 1.56.4. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.56.3...v1.56.4) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9485d52c..9e4f1a37 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -390,7 +390,7 @@ GEM rspec-mocks (~> 3.0) sidekiq (>= 5, < 8) rspec-support (3.12.1) - rubocop (1.56.3) + rubocop (1.56.4) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) @@ -477,7 +477,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.8) - unicode-display_width (2.4.2) + unicode-display_width (2.5.0) uniform_notifier (1.16.0) warden (1.2.9) rack (>= 2.0.9) From b6df1483eb238ad38d25d1d2a624ce2968ca649b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 09:22:55 +0000 Subject: [PATCH 031/590] Bump haml from 6.1.2 to 6.1.4 Bumps [haml](https://github.com/haml/haml) from 6.1.2 to 6.1.4. - [Release notes](https://github.com/haml/haml/releases) - [Changelog](https://github.com/haml/haml/blob/main/CHANGELOG.md) - [Commits](https://github.com/haml/haml/compare/v6.1.2...v6.1.4) --- updated-dependencies: - dependency-name: haml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9485d52c..9b924eef 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -183,7 +183,7 @@ GEM glob (0.3.1) globalid (1.1.0) activesupport (>= 5.0) - haml (6.1.2) + haml (6.1.4) temple (>= 0.8.2) thor tilt @@ -460,7 +460,7 @@ GEM sysexits (1.2.0) temple (0.10.2) thor (1.2.2) - tilt (2.2.0) + tilt (2.3.0) timeout (0.4.0) tldv (0.1.0) tldv-data (~> 1.0) From 8d8aa2f6ed719a6484a7c3cd36229cafe1c5eb64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 09:24:44 +0000 Subject: [PATCH 032/590] Bump fog-aws from 3.19.0 to 3.21.0 Bumps [fog-aws](https://github.com/fog/fog-aws) from 3.19.0 to 3.21.0. - [Changelog](https://github.com/fog/fog-aws/blob/master/CHANGELOG.md) - [Commits](https://github.com/fog/fog-aws/compare/v3.19.0...v3.21.0) --- updated-dependencies: - dependency-name: fog-aws dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9485d52c..426d7509 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -150,7 +150,7 @@ GEM dry-logic (~> 1.4) zeitwerk (~> 2.6) erubi (1.12.0) - excon (0.99.0) + excon (0.104.0) factory_bot (6.2.0) activesupport (>= 5.0.0) factory_bot_rails (6.2.0) @@ -162,7 +162,7 @@ GEM faker (3.1.1) i18n (>= 1.8.11, < 2) ffi (1.15.5) - fog-aws (3.19.0) + fog-aws (3.21.0) fog-core (~> 2.1) fog-json (~> 1.1) fog-xml (~> 0.1) @@ -244,9 +244,9 @@ GEM mini_mime (>= 0.1.1) marcel (1.0.2) method_source (1.0.0) - mime-types (3.4.1) + mime-types (3.5.1) mime-types-data (~> 3.2015) - mime-types-data (3.2023.0218.1) + mime-types-data (3.2023.0808) mimemagic (0.4.3) nokogiri (~> 1) rake From 215693316cc6ef853e7fddf24355a3c23daf274f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 09:53:06 +0000 Subject: [PATCH 033/590] Bump @rails/request.js from 0.0.8 to 0.0.9 Bumps [@rails/request.js](https://github.com/rails/request.js) from 0.0.8 to 0.0.9. - [Release notes](https://github.com/rails/request.js/releases) - [Commits](https://github.com/rails/request.js/compare/v0.0.8...v0.0.9) --- updated-dependencies: - dependency-name: "@rails/request.js" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 17eefbca..0593c57b 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "@hotwired/turbo-rails": "^7.3.0", "@melloware/coloris": "^0.21.1", "@popperjs/core": "^2.11", - "@rails/request.js": "^0.0.8", + "@rails/request.js": "^0.0.9", "bootstrap": "^5.2", "buffer": "^6.0.3", "cheet.js": "^0.3.3", diff --git a/yarn.lock b/yarn.lock index ba1d0abb..ea40ac95 100644 --- a/yarn.lock +++ b/yarn.lock @@ -272,10 +272,10 @@ resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-7.0.3.tgz#71f08e958883af64f6a20489318b5e95d2c6dc5b" integrity sha512-Iefl21FZD+ck1di6xSHMYzSzRiNJTHV4NrAzCfDfqc/wPz4xncrP8f2/fJ+2jzwKIaDn76UVMsALh7R5OzsF8Q== -"@rails/request.js@^0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@rails/request.js/-/request.js-0.0.8.tgz#5e2e8da15013b1af7f04d759e4e9d1cff981865c" - integrity sha512-ysHYZDl+XjBwFVXz7EI7XW+ZWiTFY8t7TrC/ahpAPt0p7NE4DZxm1nJQY9gmF4PBf+4pAYa+D/rLIGmrn1ZMvg== +"@rails/request.js@^0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@rails/request.js/-/request.js-0.0.9.tgz#89e2a575405dc07eb8a9b3d2fe04289e1f057cd0" + integrity sha512-VleYUyrA3rwKMvYnz7MI9Ada85Vekjb/WVz7NuGgDO24Y3Zy9FFSpDMQW+ea/tlftD+CdX/W/sUosRA9/HkDOQ== "@types/json-schema@^7.0.7": version "7.0.9" From a3b8ce64d7dcad7c8f012ddb5548652a9e898e79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Oct 2023 11:49:50 +0000 Subject: [PATCH 034/590] Bump postcss from 8.4.28 to 8.4.31 Bumps [postcss](https://github.com/postcss/postcss) from 8.4.28 to 8.4.31. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.28...8.4.31) --- updated-dependencies: - dependency-name: postcss dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index ba1d0abb..7a19d016 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2116,9 +2116,9 @@ postcss-value-parser@^4.2.0: integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== postcss@^8.4.27: - version "8.4.28" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.28.tgz#c6cc681ed00109072816e1557f889ef51cf950a5" - integrity sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw== + version "8.4.31" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" + integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== dependencies: nanoid "^3.3.6" picocolors "^1.0.0" From 6c7a7fba5e84aa6b44afe2c65b691762ec77a60e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 09:06:27 +0000 Subject: [PATCH 035/590] Bump sass from 1.68.0 to 1.69.0 Bumps [sass](https://github.com/sass/dart-sass) from 1.68.0 to 1.69.0. - [Release notes](https://github.com/sass/dart-sass/releases) - [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md) - [Commits](https://github.com/sass/dart-sass/compare/1.68.0...1.69.0) --- updated-dependencies: - dependency-name: sass dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 0593c57b..7bc670e2 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "croppr": "^2.3.1", "i18n-js": "^4.0", "js-cookie": "2.2.1", - "sass": "^1.68.0", + "sass": "^1.69.0", "sweetalert": "1.1.3", "toastify-js": "^1.12.0", "typescript": "^5.2.2" diff --git a/yarn.lock b/yarn.lock index 001859f2..21b7897a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2268,10 +2268,10 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -sass@^1.68.0: - version "1.68.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.68.0.tgz#0034b0cc9a50248b7d1702ac166fd25990023669" - integrity sha512-Lmj9lM/fef0nQswm1J2HJcEsBUba4wgNx2fea6yJHODREoMFnwRpZydBnX/RjyXw2REIwdkbqE4hrTo4qfDBUA== +sass@^1.69.0: + version "1.69.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.0.tgz#5195075371c239ed556280cf2f5944d234f42679" + integrity sha512-l3bbFpfTOGgQZCLU/gvm1lbsQ5mC/WnLz3djL2v4WCJBDrWm58PO+jgngcGRNnKUh6wSsdm50YaovTqskZ0xDQ== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" From 0c946fd1ba60850718fa8258f874667290785e2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 09:10:07 +0000 Subject: [PATCH 036/590] Bump net-imap from 0.3.7 to 0.4.0 Bumps [net-imap](https://github.com/ruby/net-imap) from 0.3.7 to 0.4.0. - [Release notes](https://github.com/ruby/net-imap/releases) - [Commits](https://github.com/ruby/net-imap/compare/v0.3.7...v0.4.0) --- updated-dependencies: - dependency-name: net-imap dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0aec7b99..febea898 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -262,7 +262,7 @@ GEM connection_pool (~> 2.2) net-http2 (0.18.4) http-2 (~> 0.11) - net-imap (0.3.7) + net-imap (0.4.0) date net-protocol net-pop (0.1.2) From 568409bfc59d7e67fe2f1e8547a23839f1eb02d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 09:13:31 +0000 Subject: [PATCH 037/590] Bump haml_lint from 0.50.0 to 0.51.0 Bumps [haml_lint](https://github.com/sds/haml-lint) from 0.50.0 to 0.51.0. - [Release notes](https://github.com/sds/haml-lint/releases) - [Changelog](https://github.com/sds/haml-lint/blob/main/CHANGELOG.md) - [Commits](https://github.com/sds/haml-lint/compare/v0.50.0...v0.51.0) --- updated-dependencies: - dependency-name: haml_lint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0aec7b99..0457cf88 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -187,8 +187,8 @@ GEM temple (>= 0.8.2) thor tilt - haml_lint (0.50.0) - haml (>= 4.0, < 6.2) + haml_lint (0.51.0) + haml (>= 4.0) parallel (~> 1.10) rainbow rubocop (>= 1.0) @@ -279,7 +279,7 @@ GEM openssl (3.2.0) orm_adapter (0.5.0) parallel (1.23.0) - parser (3.2.2.3) + parser (3.2.2.4) ast (~> 2.4.1) racc pg (1.5.4) @@ -458,7 +458,7 @@ GEM activesupport (>= 5.2) sprockets (>= 3.0.0) sysexits (1.2.0) - temple (0.10.2) + temple (0.10.3) thor (1.2.2) tilt (2.3.0) timeout (0.4.0) From 5d958259c0e1f6458197c5a18f0f8ee71cf28ef9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 09:13:56 +0000 Subject: [PATCH 038/590] Bump bullet from 7.0.7 to 7.1.1 Bumps [bullet](https://github.com/flyerhzm/bullet) from 7.0.7 to 7.1.1. - [Changelog](https://github.com/flyerhzm/bullet/blob/main/CHANGELOG.md) - [Commits](https://github.com/flyerhzm/bullet/compare/7.0.7...7.1.1) --- updated-dependencies: - dependency-name: bullet dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0aec7b99..738aead0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -92,7 +92,7 @@ GEM actionpack (>= 5.2) activemodel (>= 5.2) builder (3.2.4) - bullet (7.0.7) + bullet (7.1.1) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) carrierwave (2.1.0) From 9e35c036b19514451b69cbfe2a2062f33b328cd0 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sat, 14 Oct 2023 20:57:09 +0200 Subject: [PATCH 039/590] Rewrite WebPush enable handler to properly catch errors --- .../retrospring/features/webpush/enable.ts | 81 ++++++++++--------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/app/javascript/retrospring/features/webpush/enable.ts b/app/javascript/retrospring/features/webpush/enable.ts index c92aed64..3a77485a 100644 --- a/app/javascript/retrospring/features/webpush/enable.ts +++ b/app/javascript/retrospring/features/webpush/enable.ts @@ -3,52 +3,53 @@ import I18n from "retrospring/i18n"; import { showNotification } from "utilities/notifications"; import { Buffer } from "buffer"; -export function enableHandler (event: Event): void { +export async function enableHandler (event: Event): Promise { event.preventDefault(); const sender = event.target as HTMLButtonElement; try { - getServiceWorker() - .then(subscribe) - .then(async subscription => { - return Notification.requestPermission().then(permission => { - if (permission != "granted") { - return; - } + const registration = await getServiceWorker(); + const subscription = await subscribe(registration); + const permission = await Notification.requestPermission(); - post('/ajax/webpush', { - body: { - subscription - }, - contentType: 'application/json' - }).then(async response => { - const data = await response.json; - - if (data.success) { - new Notification(I18n.translate("frontend.push_notifications.subscribe.success.title"), { - body: I18n.translate("frontend.push_notifications.subscribe.success.body") - }); - - document.querySelectorAll('button[data-action="push-disable"], button[data-action="push-remove-all"]') - .forEach(button => button.classList.remove('d-none')); - - sender.classList.add('d-none'); - document.querySelector('.push-settings')?.classList.add('d-none'); - localStorage.setItem('dismiss-push-settings-prompt', 'true'); - - document.getElementById('subscription-count').textContent = data.message; - } else { - new Notification(I18n.translate("frontend.push_notifications.fail.title"), { - body: I18n.translate("frontend.push_notifications.fail.body") - }); - } - }); - }); - }); - } catch (error) { - console.error("Failed to set up push notifications", error); - showNotification(I18n.translate("frontend.push_notifications.setup_fail")); + if (permission != "granted") { + return; } + + const response = await post('/ajax/webpush', { + body: { + subscription + }, + contentType: 'application/json' + }); + + const data = await response.json; + + if (data.success) { + new Notification(I18n.translate("frontend.push_notifications.subscribe.success.title"), { + body: I18n.translate("frontend.push_notifications.subscribe.success.body") + }); + + document.querySelectorAll('button[data-action="push-disable"], button[data-action="push-remove-all"]') + .forEach(button => button.classList.remove('d-none')); + + sender.classList.add('d-none'); + document.querySelector('.push-settings')?.classList.add('d-none'); + localStorage.setItem('dismiss-push-settings-prompt', 'true'); + + const subscriptionCountElement = document.getElementById('subscription-count'); + if (subscriptionCountElement != null) { + subscriptionCountElement.textContent = data.message; + } + } else { + new Notification(I18n.translate("frontend.push_notifications.fail.title"), { + body: I18n.translate("frontend.push_notifications.fail.body") + }); + } + } catch (error) { + console.error("Failed to set up push notifications", error); + showNotification(I18n.translate("frontend.push_notifications.setup_fail"), false); + } } async function getServiceWorker(): Promise { From ec05b3c062a33ae1c4d057f77bf8c91fee559e90 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sat, 14 Oct 2023 21:14:02 +0200 Subject: [PATCH 040/590] Update `hcaptcha` gem to forked version with fixed Turbo handling --- Gemfile | 2 +- Gemfile.lock | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index dac7c564..02cf3416 100644 --- a/Gemfile +++ b/Gemfile @@ -31,7 +31,7 @@ gem "fog-aws" gem "fog-core" gem "fog-local" gem "haml", "~> 6.1" -gem "hcaptcha", "~> 7.0" +gem "hcaptcha", git: "https://github.com/raccube/hcaptcha", ref: "fix/flash-in-turbo-streams" gem "mini_magick" gem "oj" gem "rpush" diff --git a/Gemfile.lock b/Gemfile.lock index ae7fcfbf..539ed2e2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,6 +6,14 @@ GIT carrierwave (>= 0.5, <= 2.1) mime-types (>= 3.0.0) +GIT + remote: https://github.com/raccube/hcaptcha + revision: f8de70ee2d629ac34395902dbee724c21297960c + ref: fix/flash-in-turbo-streams + specs: + hcaptcha (7.1.0) + json + GEM remote: https://rubygems.org/ specs: @@ -193,8 +201,6 @@ GEM rainbow rubocop (>= 1.0) sysexits (~> 1.1) - hcaptcha (7.1.0) - json hkdf (0.3.0) http-2 (0.11.0) httparty (0.21.0) @@ -520,7 +526,7 @@ DEPENDENCIES fog-local haml (~> 6.1) haml_lint - hcaptcha (~> 7.0) + hcaptcha! httparty i18n-js (= 4.0) jsbundling-rails (~> 1.2) From d40519dffa1f0db55b055489c0011371b73a3bdf Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 06:39:50 +0200 Subject: [PATCH 041/590] Handle Rails validation errors in TurboStreamable concern --- app/controllers/concerns/turbo_streamable.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/concerns/turbo_streamable.rb b/app/controllers/concerns/turbo_streamable.rb index 5066bc05..da9a3a95 100644 --- a/app/controllers/concerns/turbo_streamable.rb +++ b/app/controllers/concerns/turbo_streamable.rb @@ -23,6 +23,8 @@ module TurboStreamable render_error t("errors.parameter_error", parameter: e.instance_of?(KeyError) ? e.key : e.param.capitalize) rescue Dry::Types::CoercionError, Dry::Types::ConstraintError render_error t("errors.invalid_parameter") + rescue ActiveRecord::RecordInvalid => e + render_error e.record.errors.full_messages.flatten.join(" ") rescue ActiveRecord::RecordNotFound render_error t("errors.record_not_found") end From f3f8e99045c16d091333cb9d91985ab3bead15ad Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 06:40:32 +0200 Subject: [PATCH 042/590] Use `length` validation instead of `presence` for `MuteRule` --- app/models/mute_rule.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/mute_rule.rb b/app/models/mute_rule.rb index 3e2a66af..4ca5e15d 100644 --- a/app/models/mute_rule.rb +++ b/app/models/mute_rule.rb @@ -3,7 +3,7 @@ class MuteRule < ApplicationRecord belongs_to :user - validates :muted_phrase, presence: true + validates :muted_phrase, length: { minimum: 1 } def applies_to?(post) !!(post.content =~ /\b#{Regexp.escape(muted_phrase)}\b/i) From 9f8450a83ca8631a23ac9e933a6a3f3f1b029c47 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 06:40:47 +0200 Subject: [PATCH 043/590] Add frontend validation for mute rule creation --- app/views/settings/mutes/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/settings/mutes/_form.html.haml b/app/views/settings/mutes/_form.html.haml index 33213d32..8cd73afb 100644 --- a/app/views/settings/mutes/_form.html.haml +++ b/app/views/settings/mutes/_form.html.haml @@ -1,6 +1,6 @@ #form.form-group %form{ action: settings_muted_path, method: "post" } .input-group - %input.form-control#muted_phrase{ name: :muted_phrase, placeholder: t(".placeholder"), data: { controller: :autofocus } } + %input.form-control#muted_phrase{ name: :muted_phrase, placeholder: t(".placeholder"), required: true, minlength: 1, data: { controller: :autofocus } } .input-group-append %button.btn.btn-primary{ type: "submit" }= t("voc.add") From 454438091bd86431dacab8a7d50383b3525c35d3 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 06:42:59 +0200 Subject: [PATCH 044/590] Use explicit `create!` call in mute rule creation use case --- lib/use_case/mute_rule/create.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/use_case/mute_rule/create.rb b/lib/use_case/mute_rule/create.rb index 68a587aa..eee45dd6 100644 --- a/lib/use_case/mute_rule/create.rb +++ b/lib/use_case/mute_rule/create.rb @@ -7,7 +7,7 @@ module UseCase option :phrase, type: Types::Coercible::String def call - rule = ::MuteRule.create( + rule = ::MuteRule.create!( user:, muted_phrase: phrase ) From 6efee0053e528f8fd2ec93d81cbc9b5a62aa83bd Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 06:55:13 +0200 Subject: [PATCH 045/590] Adjust mute rule test case to now expect an error --- spec/lib/use_case/mute_rule/create_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/lib/use_case/mute_rule/create_spec.rb b/spec/lib/use_case/mute_rule/create_spec.rb index 4321048e..24e267d9 100644 --- a/spec/lib/use_case/mute_rule/create_spec.rb +++ b/spec/lib/use_case/mute_rule/create_spec.rb @@ -11,8 +11,8 @@ describe UseCase::MuteRule::Create do context "phrase is empty" do let(:phrase) { "" } - it "does not create the rule" do - expect { subject }.not_to(change { MuteRule.count }) + it "raises an error" do + expect { subject }.to raise_error(ActiveRecord::RecordInvalid) end end From bff579661fdca286e908399216ccdb4ce1b437ab Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 07:12:55 +0200 Subject: [PATCH 046/590] Add spec for invalid record toasts in `TurboStreamable` concern --- spec/controllers/concerns/turbo_streamable_spec.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spec/controllers/concerns/turbo_streamable_spec.rb b/spec/controllers/concerns/turbo_streamable_spec.rb index 3a2c9c60..491c159a 100644 --- a/spec/controllers/concerns/turbo_streamable_spec.rb +++ b/spec/controllers/concerns/turbo_streamable_spec.rb @@ -6,7 +6,7 @@ describe TurboStreamable, type: :controller do controller do include TurboStreamable - turbo_stream_actions :create, :blocked, :not_found + turbo_stream_actions :create, :blocked, :not_found, :invalid_record def create params.require :message @@ -25,6 +25,10 @@ describe TurboStreamable, type: :controller do def not_found raise ActiveRecord::RecordNotFound end + + def invalid_record + ::MuteRule.create!(muted_phrase: "", user: FactoryBot.create(:user)) + end end before do @@ -32,6 +36,7 @@ describe TurboStreamable, type: :controller do get "create" => "anonymous#create" get "blocked" => "anonymous#blocked" get "not_found" => "anonymous#not_found" + get "invalid_record" => "anonymous#invalid_record" end end @@ -68,4 +73,5 @@ describe TurboStreamable, type: :controller do it_behaves_like "it returns a toast as Turbo Stream response", :create, "Message is required" it_behaves_like "it returns a toast as Turbo Stream response", :blocked, "You have been blocked from performing this request" it_behaves_like "it returns a toast as Turbo Stream response", :not_found, "Record not found" + it_behaves_like "it returns a toast as Turbo Stream response", :invalid_record, "too short" end From 905348395251bd987e03c267fde6dc8eb44859fd Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 07:20:32 +0200 Subject: [PATCH 047/590] Fix rubocop nits --- spec/controllers/concerns/turbo_streamable_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/concerns/turbo_streamable_spec.rb b/spec/controllers/concerns/turbo_streamable_spec.rb index 491c159a..19e0079c 100644 --- a/spec/controllers/concerns/turbo_streamable_spec.rb +++ b/spec/controllers/concerns/turbo_streamable_spec.rb @@ -27,7 +27,7 @@ describe TurboStreamable, type: :controller do end def invalid_record - ::MuteRule.create!(muted_phrase: "", user: FactoryBot.create(:user)) + MuteRule.create!(muted_phrase: "", user: FactoryBot.create(:user)) end end From 3afa52c59e6098bfa6a9853046d2bd1ecdf6fd63 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 07:32:31 +0200 Subject: [PATCH 048/590] Fix haml-lint nits --- app/views/settings/mutes/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/settings/mutes/_form.html.haml b/app/views/settings/mutes/_form.html.haml index 8cd73afb..ba13cd14 100644 --- a/app/views/settings/mutes/_form.html.haml +++ b/app/views/settings/mutes/_form.html.haml @@ -1,6 +1,6 @@ #form.form-group %form{ action: settings_muted_path, method: "post" } .input-group - %input.form-control#muted_phrase{ name: :muted_phrase, placeholder: t(".placeholder"), required: true, minlength: 1, data: { controller: :autofocus } } + %input.form-control#muted-phrase{ name: :muted_phrase, placeholder: t(".placeholder"), required: true, minlength: 1, data: { controller: :autofocus } } .input-group-append %button.btn.btn-primary{ type: "submit" }= t("voc.add") From ac0548932917cd08229b6ca759673f0ff4e93c6a Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 08:23:11 +0200 Subject: [PATCH 049/590] Limit comment toggle querySelector call to nearest answerbox --- .../retrospring/features/answerbox/comment/hotkey.ts | 7 +++++-- .../retrospring/features/answerbox/comment/toggle.ts | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/javascript/retrospring/features/answerbox/comment/hotkey.ts b/app/javascript/retrospring/features/answerbox/comment/hotkey.ts index 0e15dd7f..e56cb0e9 100644 --- a/app/javascript/retrospring/features/answerbox/comment/hotkey.ts +++ b/app/javascript/retrospring/features/answerbox/comment/hotkey.ts @@ -1,7 +1,10 @@ export function commentHotkeyHandler(event: Event): void { const button = event.target as HTMLButtonElement; const id = button.dataset.aId; + const answerbox = button.closest('.answerbox'); - document.querySelector(`#ab-comments-section-${id}`).classList.remove('d-none'); - document.querySelector(`[name="ab-comment-new"][data-a-id="${id}"]`).focus(); + if (answerbox !== null) { + answerbox.querySelector(`#ab-comments-section-${id}`).classList.toggle('d-none'); + answerbox.querySelector(`[name="ab-comment-new"][data-a-id="${id}"]`).focus(); + } } diff --git a/app/javascript/retrospring/features/answerbox/comment/toggle.ts b/app/javascript/retrospring/features/answerbox/comment/toggle.ts index 578351f8..c53b9cfc 100644 --- a/app/javascript/retrospring/features/answerbox/comment/toggle.ts +++ b/app/javascript/retrospring/features/answerbox/comment/toggle.ts @@ -1,6 +1,9 @@ export function commentToggleHandler(event: Event): void { const button = event.target as HTMLButtonElement; const id = button.dataset.aId; + const answerbox = button.closest('.answerbox'); - document.querySelector(`#ab-comments-section-${id}`).classList.toggle('d-none'); -} \ No newline at end of file + if (answerbox !== null) { + answerbox.querySelector(`#ab-comments-section-${id}`).classList.toggle('d-none'); + } +} From ace3df932a898396f6fb612f0c82a207d4bb8302 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 10:09:49 +0200 Subject: [PATCH 050/590] Disable `Metrics/*Length` and `AbcSize` cops --- .rubocop.yml | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index ed74d1c9..41696d20 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -31,39 +31,25 @@ Lint/NestedMethodDefinition: ### Metrics Metrics/AbcSize: - Max: 20 - Exclude: - - 'db/**/*' + Enabled: false Layout/LineLength: Enabled: false Metrics/MethodLength: - Max: 15 - Exclude: - - 'db/migrate/*.rb' + Enabled: false Metrics/BlockLength: - Exclude: - - '*.gemspec' - - '**/*.rake' - - 'api/**/*' - - 'app/api/routes.rb' - - 'config/initialize/**/*' - - 'config/initializers/**/*' - - 'spec/**/*' + Enabled: false Metrics/ClassLength: - Exclude: - - spec/**/* + Enabled: false Metrics/CyclomaticComplexity: Severity: refactor Metrics/ModuleLength: - Exclude: - - 'app/api/routes.rb' - - 'spec/requests/**/*' + Enabled: false ### Style / Layout From f6e26f1751af92a69382377f4f74690cde4076f4 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 10:21:46 +0200 Subject: [PATCH 051/590] Remove superfluous rubocop:disable comments --- Rakefile | 2 +- app/controllers/ajax/web_push_controller.rb | 2 +- app/controllers/inbox_controller.rb | 2 +- app/models/user.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Rakefile b/Rakefile index 17ba7dcf..dfd42972 100644 --- a/Rakefile +++ b/Rakefile @@ -7,7 +7,7 @@ require File.expand_path("config/application", __dir__) Rails.application.load_tasks -namespace :justask do # rubocop:disable Metrics/BlockLength +namespace :justask do desc "Gives admin status to a user." task :admin, [:screen_name] => :environment do |_t, args| abort "screen name required" if args[:screen_name].nil? diff --git a/app/controllers/ajax/web_push_controller.rb b/app/controllers/ajax/web_push_controller.rb index 4dd9ecdd..04d7fb40 100644 --- a/app/controllers/ajax/web_push_controller.rb +++ b/app/controllers/ajax/web_push_controller.rb @@ -41,7 +41,7 @@ class Ajax::WebPushController < AjaxController @response[:message] = t(".subscription_count", count: current_user.web_push_subscriptions.count) end - def unsubscribe # rubocop:disable Metrics/AbcSize + def unsubscribe removed = if params.key?(:endpoint) current_user.web_push_subscriptions.where("subscription ->> 'endpoint' = ?", params[:endpoint]).destroy_all else diff --git a/app/controllers/inbox_controller.rb b/app/controllers/inbox_controller.rb index 7f3db342..56b01f5a 100644 --- a/app/controllers/inbox_controller.rb +++ b/app/controllers/inbox_controller.rb @@ -3,7 +3,7 @@ class InboxController < ApplicationController before_action :authenticate_user! - def show # rubocop:disable Metrics/MethodLength + def show find_author find_inbox_entries diff --git a/app/models/user.rb b/app/models/user.rb index 2b2241e0..762f7020 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class User < ApplicationRecord # rubocop:disable Metrics/ClassLength +class User < ApplicationRecord include User::Relationship include User::Relationship::Follow include User::Relationship::Block From 9658f1083886d2d680c531ca328fda2767cc8e99 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 10:34:19 +0200 Subject: [PATCH 052/590] Don't check `Style/RedundantSelf` in the models directory --- .rubocop.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 41696d20..12052185 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -123,3 +123,7 @@ Style/TrailingCommaInHashLiteral: Style/TrailingCommaInArguments: EnforcedStyleForMultiline: consistent_comma + +Style/RedundantSelf: + Exclude: + - app/models/**/* From ffcaa5c4d9f73729f9c5ccd1d71edc6c6a907657 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 10:35:52 +0200 Subject: [PATCH 053/590] Remove superfluous rubocop:disable comments --- app/models/user.rb | 4 ---- app/models/user/reaction_methods.rb | 2 -- app/models/user/relationship/follow.rb | 2 -- 3 files changed, 8 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 762f7020..1f157482 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -117,10 +117,8 @@ class User < ApplicationRecord # @param question [Question] the question to answer # @param content [String] the answer content def answer(question, content) - # rubocop:disable Style/RedundantSelf raise Errors::AnsweringOtherBlockedSelf if question.user&.blocking?(self) raise Errors::AnsweringSelfBlockedOther if self.blocking?(question.user) - # rubocop:enable Style/RedundantSelf Retrospring::Metrics::QUESTIONS_ANSWERED.increment @@ -132,10 +130,8 @@ class User < ApplicationRecord def answered?(question) = question.answers.pluck(:user_id).include? id def comment(answer, content) - # rubocop:disable Style/RedundantSelf raise Errors::CommentingSelfBlockedOther if self.blocking?(answer.user) raise Errors::CommentingOtherBlockedSelf if answer.user.blocking?(self) - # rubocop:enable Style/RedundantSelf Retrospring::Metrics::COMMENTS_CREATED.increment diff --git a/app/models/user/reaction_methods.rb b/app/models/user/reaction_methods.rb index 18ecac25..fa3e6545 100644 --- a/app/models/user/reaction_methods.rb +++ b/app/models/user/reaction_methods.rb @@ -4,10 +4,8 @@ module User::ReactionMethods # smiles an answer or comment # @param item [ApplicationRecord] the answer/comment to smile def smile(item) - # rubocop:disable Style/RedundantSelf raise Errors::ReactingSelfBlockedOther if self.blocking?(item.user) raise Errors::ReactingOtherBlockedSelf if item.user.blocking?(self) - # rubocop:enable Style/RedundantSelf ::Appendable::Reaction.create!(user: self, parent: item, content: "🙂") end diff --git a/app/models/user/relationship/follow.rb b/app/models/user/relationship/follow.rb index 4e034821..50dc321e 100644 --- a/app/models/user/relationship/follow.rb +++ b/app/models/user/relationship/follow.rb @@ -19,10 +19,8 @@ class User # Follow an user def follow(target_user) raise Errors::FollowingSelf if target_user == self - # rubocop:disable Style/RedundantSelf raise Errors::FollowingOtherBlockedSelf if target_user.blocking?(self) raise Errors::FollowingSelfBlockedOther if self.blocking?(target_user) - # rubocop:enable Style/RedundantSelf create_relationship(active_follow_relationships, target_user) end From 439797ee1e2ba0727a046f9aeb240dcfe2616554 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 12:50:55 +0200 Subject: [PATCH 054/590] Fix `build-image` workflow (#1375) Co-authored-by: Georg Gadinger --- Containerfile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Containerfile b/Containerfile index 700b458e..249f7323 100644 --- a/Containerfile +++ b/Containerfile @@ -1,6 +1,6 @@ # Container image for a production Retrospring setup -FROM registry.opensuse.org/opensuse/leap:15.4 +FROM registry.opensuse.org/opensuse/leap:15.5 LABEL org.opencontainers.image.title="Retrospring (production)" LABEL org.opencontainers.image.description="Image containing everything to run Retrospring in production mode. Do not use this for development." @@ -15,7 +15,8 @@ ARG BUNDLER_VERSION=2.3.18 ENV RAILS_ENV=production # update and install dependencies -RUN zypper up -y \ +RUN zypper addrepo https://download.opensuse.org/repositories/devel:languages:nodejs/15.5/devel:languages:nodejs.repo \ + && zypper --gpg-auto-import-keys up -y \ && zypper in -y \ # build dependencies (ruby-install) automake \ @@ -31,12 +32,13 @@ RUN zypper up -y \ tar \ xz \ zlib-devel \ + curl \ # build dependencies (app) gcc-c++ \ git \ libidn-devel \ - nodejs14 \ - npm14 \ + nodejs16 \ + npm16 \ postgresql-devel \ # runtime dependencies ImageMagick \ From e3e45acf9f7f6202ef41e9c1039ab067df811da7 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Sun, 15 Oct 2023 13:13:52 +0200 Subject: [PATCH 055/590] Use Node 16 across the project --- .docker/ruby/Dockerfile | 2 +- .github/workflows/lint.yml | 8 ++++---- .github/workflows/retrospring.yml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.docker/ruby/Dockerfile b/.docker/ruby/Dockerfile index 205ec80a..6e6e33d2 100644 --- a/.docker/ruby/Dockerfile +++ b/.docker/ruby/Dockerfile @@ -8,7 +8,7 @@ ARG GID=1000 RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list -RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - +RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - RUN apt-get update -qq \ && apt-get install -y --no-install-recommends build-essential \ diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 237b9882..297ca717 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -43,10 +43,10 @@ jobs: uses: tj-actions/changed-files@v39 with: files: "**/*.ts" - - name: Set up Node 14 + - name: Set up Node 16 uses: actions/setup-node@v3 with: - node-version: '14' + node-version: '16' cache: 'yarn' if: steps.changed-files.outputs.any_changed == 'true' - name: Install node modules @@ -92,10 +92,10 @@ jobs: uses: tj-actions/changed-files@v39 with: files: "**/*.scss" - - name: Set up Node 14 + - name: Set up Node 16 uses: actions/setup-node@v3 with: - node-version: '14' + node-version: '16' cache: 'yarn' if: steps.changed-files.outputs.any_changed == 'true' - name: Install node modules diff --git a/.github/workflows/retrospring.yml b/.github/workflows/retrospring.yml index e46aeeaa..4ab0ab64 100644 --- a/.github/workflows/retrospring.yml +++ b/.github/workflows/retrospring.yml @@ -48,10 +48,10 @@ jobs: uses: ruby/setup-ruby@v1 with: bundler-cache: true - - name: Set up Node 14 + - name: Set up Node 16 uses: actions/setup-node@v3 with: - node-version: '14' + node-version: '16' cache: 'yarn' - name: Copy default configuration run: | From 849d4f74f263e6327c838f680598de189a7bcf9d Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Sat, 11 Mar 2023 19:48:04 +0100 Subject: [PATCH 056/590] Move comments to a turbo frame --- app/controllers/ajax/comment_controller.rb | 4 +++- app/controllers/comment_controller.rb | 10 ++++++++++ app/views/answerbox/_comments.html.haml | 21 ++------------------ app/views/application/_answerbox.html.haml | 23 ++++++++++++++++++++-- app/views/comment/index.html.haml | 3 +++ config/locales/views.en.yml | 8 ++++---- config/locales/voc.en.yml | 1 + config/routes.rb | 1 + 8 files changed, 45 insertions(+), 26 deletions(-) create mode 100644 app/controllers/comment_controller.rb create mode 100644 app/views/comment/index.html.haml diff --git a/app/controllers/ajax/comment_controller.rb b/app/controllers/ajax/comment_controller.rb index 72dd305e..c2ef3341 100644 --- a/app/controllers/ajax/comment_controller.rb +++ b/app/controllers/ajax/comment_controller.rb @@ -14,10 +14,12 @@ class Ajax::CommentController < AjaxController return end + comments = Comment.where(answer:).includes([{user: :profile}, :smiles]) + @response[:status] = :okay @response[:message] = t(".success") @response[:success] = true - @response[:render] = render_to_string(partial: 'answerbox/comments', locals: { a: answer }) + @response[:render] = render_to_string(partial: 'answerbox/comments', locals: { a: answer, comments: }) @response[:count] = answer.comment_count end diff --git a/app/controllers/comment_controller.rb b/app/controllers/comment_controller.rb new file mode 100644 index 00000000..62def069 --- /dev/null +++ b/app/controllers/comment_controller.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class CommentController < ApplicationController + def index + answer = Answer.find(params[:id]) + comments = Comment.where(answer:).includes([{user: :profile}, :smiles]) + + render "index", locals: { a: answer, comments: } + end +end diff --git a/app/views/answerbox/_comments.html.haml b/app/views/answerbox/_comments.html.haml index 023990e9..62a1035c 100644 --- a/app/views/answerbox/_comments.html.haml +++ b/app/views/answerbox/_comments.html.haml @@ -1,8 +1,8 @@ -- if a.comments.all.count.zero? +- if comments.all.count.zero? = t(".none") - else %ul.comment__container - - a.comments.order(:created_at).each do |comment| + - comments.order(:created_at).each do |comment| %li.comment{ data: { comment_id: comment.id } } %div{ style: "height: 0; width: 0" }= render "modal/comment_smiles", comment: comment .d-flex @@ -24,20 +24,3 @@ %button.btn.btn-link.btn-sm.dropdown-toggle{ data: { bs_toggle: :dropdown }, aria: { expanded: false } } %span.caret = render "actions/comment", comment: comment, answer: a -- if user_signed_in? - %button.d-none{ name: "ab-open-and-comment", data: { a_id: a.id, selection_hotkey: "c" } } - .comment__compose-wrapper{ - name: "ab-comment-new-group", - data: { a_id: a.id, controller: "character-count", character_count_max_value: 512 } - } - .form-group.has-feedback.comment__input-group.input-group - %textarea.form-control.comment__input{ type: :text, placeholder: t(".placeholder"), name: "ab-comment-new", data: { a_id: a.id, "character-count-target": "input" } } - .comment__submit-wrapper - %button.btn.btn-primary{ - type: :button, - name: "ab-comment-new-submit", - title: t(".action"), - data: { a_id: a.id, "character-count-target": "action" } - } - %i.fa.fa-paper-plane-o - %span.text-muted.form-control-feedback.comment__character-count{ id: "ab-comment-charcount-#{a.id}", data: { "character-count-target": "counter" } } 512 diff --git a/app/views/application/_answerbox.html.haml b/app/views/application/_answerbox.html.haml index b84a5f17..c6236f3c 100644 --- a/app/views/application/_answerbox.html.haml +++ b/app/views/application/_answerbox.html.haml @@ -35,5 +35,24 @@ .col-md-6.d-md-flex.answerbox__actions = render "answerbox/actions", a:, display_all:, subscribed_answer_ids: .card-footer{ id: "ab-comments-section-#{a.id}", class: display_all.nil? ? "d-none" : nil } - %div{ id: "ab-smiles-#{a.id}" }= render "answerbox/smiles", a: a - %div{ id: "ab-comments-#{a.id}" }= render "answerbox/comments", a: a + = turbo_frame_tag("ab-comments-list-#{a.id}", src: comments_path(a.question, a), loading: :lazy) do + .d-flex.justify-content-center + .spinner-border{ role: :status } + .visually-hidden= t("voc.loading") + - if user_signed_in? + %button.d-none{ name: "ab-open-and-comment", data: { a_id: a.id, selection_hotkey: "c" } } + .comment__compose-wrapper{ + name: "ab-comment-new-group", + data: { a_id: a.id, controller: "character-count", character_count_max_value: 512 } + } + .form-group.has-feedback.comment__input-group.input-group + %textarea.form-control.comment__input{ type: :text, placeholder: t(".comments.placeholder"), name: "ab-comment-new", data: { a_id: a.id, "character-count-target": "input" } } + .comment__submit-wrapper + %button.btn.btn-primary{ + type: :button, + name: "ab-comment-new-submit", + title: t(".comments.action"), + data: { a_id: a.id, "character-count-target": "action" } + } + %i.fa.fa-paper-plane-o + %span.text-muted.form-control-feedback.comment__character-count{ id: "ab-comment-charcount-#{a.id}", data: { "character-count-target": "counter" } } 512 diff --git a/app/views/comment/index.html.haml b/app/views/comment/index.html.haml new file mode 100644 index 00000000..d13a5cf0 --- /dev/null +++ b/app/views/comment/index.html.haml @@ -0,0 +1,3 @@ += turbo_frame_tag "ab-comments-list-#{a.id}" do + %div{ id: "ab-smiles-#{a.id}" }= render "answerbox/smiles", a: + %div{ id: "ab-comments-#{a.id}" }= render "answerbox/comments", a:, comments: diff --git a/config/locales/views.en.yml b/config/locales/views.en.yml index 20994bce..473f38bb 100644 --- a/config/locales/views.en.yml +++ b/config/locales/views.en.yml @@ -117,18 +117,18 @@ en: actions: share: title: "Share" - comments: - none: "There are no comments yet." - placeholder: "Comment..." - action: "Post comment" smiles: none: "No one smiled this yet." + comments: + none: "There are no comments yet." application: answerbox: read: "Read the entire answer" answered: "%{hide} %{user}" # resolves into "Answered by %{user}" hide: "Answered by" pinned: "Pinned" + comments: + placeholder: "Comment…" questionbox: title: "Ask something!" placeholder: "Type your question here…" diff --git a/config/locales/voc.en.yml b/config/locales/voc.en.yml index a05407eb..01f1ff9c 100644 --- a/config/locales/voc.en.yml +++ b/config/locales/voc.en.yml @@ -12,6 +12,7 @@ en: follow: "Follow" format_markdown: "Styling with Markdown is supported" load: "Load more" + loading: "Loading…" login: "Sign in" logout: "Sign out" mute: "Mute" diff --git a/config/routes.rb b/config/routes.rb index 3af4b3a8..85fc5a6e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -153,6 +153,7 @@ Rails.application.routes.draw do get "/@:username/a/:id", to: "answer#show", as: :answer post "/@:username/a/:id/pin", to: "answer#pin", as: :pin_answer delete "/@:username/a/:id/pin", to: "answer#unpin", as: :unpin_answer + get "/@:username/a/:id/comments", to: "comment#index", as: :comments get "/@:username/q/:id", to: "question#show", as: :question get "/@:username/followers", to: "user#followers", as: :show_user_followers get "/@:username/followings", to: "user#followings", as: :show_user_followings From adf294e6cbd0dadce724a9a3efc2e581aa4eafdb Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Fri, 5 May 2023 15:58:19 +0200 Subject: [PATCH 057/590] Add tests for viewing comments --- app/controllers/comment_controller.rb | 4 +- app/views/comment/index.html.haml | 2 +- spec/controllers/comment_controller_spec.rb | 37 +++++++ .../answerbox/_comments.html.haml_spec.rb | 101 ++++++++++++++++++ 4 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 spec/controllers/comment_controller_spec.rb create mode 100644 spec/views/answerbox/_comments.html.haml_spec.rb diff --git a/app/controllers/comment_controller.rb b/app/controllers/comment_controller.rb index 62def069..0b61f2eb 100644 --- a/app/controllers/comment_controller.rb +++ b/app/controllers/comment_controller.rb @@ -3,8 +3,8 @@ class CommentController < ApplicationController def index answer = Answer.find(params[:id]) - comments = Comment.where(answer:).includes([{user: :profile}, :smiles]) + @comments = Comment.where(answer:).includes([{user: :profile}, :smiles]) - render "index", locals: { a: answer, comments: } + render "index", locals: { a: answer } end end diff --git a/app/views/comment/index.html.haml b/app/views/comment/index.html.haml index d13a5cf0..52cad691 100644 --- a/app/views/comment/index.html.haml +++ b/app/views/comment/index.html.haml @@ -1,3 +1,3 @@ = turbo_frame_tag "ab-comments-list-#{a.id}" do %div{ id: "ab-smiles-#{a.id}" }= render "answerbox/smiles", a: - %div{ id: "ab-comments-#{a.id}" }= render "answerbox/comments", a:, comments: + %div{ id: "ab-comments-#{a.id}" }= render "answerbox/comments", a:, comments: @comments diff --git a/spec/controllers/comment_controller_spec.rb b/spec/controllers/comment_controller_spec.rb new file mode 100644 index 00000000..ace2aad8 --- /dev/null +++ b/spec/controllers/comment_controller_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe CommentController, type: :controller do + describe "#index" do + shared_examples_for "succeeds" do + it "returns the correct response" do + subject + expect(response).to have_rendered("comment/index") + expect(response).to have_http_status(200) + expect(assigns(:comments)).to eq(comments) + expect(assigns(:comments)).to_not include(unrelated_comment) + end + end + + subject { get :index, params: { username: answer_author.screen_name, id: answer.id } } + + let(:answer_author) { FactoryBot.create(:user) } + let(:answer) { FactoryBot.create(:answer, user: answer_author) } + let(:commenter) { FactoryBot.create(:user) } + let!(:comments) { FactoryBot.create_list(:comment, num_comments, answer:, user: commenter) } + let!(:unrelated_comment) do + FactoryBot.create(:comment, + answer: FactoryBot.create(:answer, user: FactoryBot.create(:user)), + user: commenter,) + end + + [0, 1, 5, 30].each do |num_comments| + context "#{num_comments} comments" do + let(:num_comments) { num_comments } + + include_examples "succeeds" + end + end + end +end diff --git a/spec/views/answerbox/_comments.html.haml_spec.rb b/spec/views/answerbox/_comments.html.haml_spec.rb new file mode 100644 index 00000000..90090069 --- /dev/null +++ b/spec/views/answerbox/_comments.html.haml_spec.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe "answerbox/_comments.html.haml", type: :view do + subject(:rendered) do + render partial: "answerbox/comments", locals: { + comments:, a: + } + end + + let(:a) { FactoryBot.create(:answer, user: FactoryBot.create(:user)) } + let(:comments) { Comment.all } + + context "no comments" do + it "shows an empty list" do + expect(rendered).to eq("There are no comments yet.\n") + end + end + + context "comments are present" do + let!(:expected_comments) { FactoryBot.create_list(:comment, 5, answer: a, user: FactoryBot.create(:user)) } + + it "shows a list of comments" do + html = Nokogiri::HTML.parse(rendered) + selector = %(li.comment .comment__content) + comment_elements = html.css(selector) + expect(comment_elements.size).to eq(5) + expect(comment_elements.map(&:text).map(&:strip)).to eq(expected_comments.map(&:content)) + end + end + + context "containing your own comment" do + let(:user) { FactoryBot.create(:user) } + let!(:comment) { FactoryBot.create(:comment, user:, answer: a) } + + before do + sign_in user + end + + it "shows the delete option" do + html = Nokogiri::HTML.parse(rendered) + selector = %(li.comment[data-comment-id="#{comment.id}"] .btn-group a[data-action="ab-comment-destroy"]) + element = html.css(selector) + expect(element).to_not be_nil + expect(element.text.strip).to eq("Delete") + end + end + + context "containing someone else's comment" do + let(:user) { FactoryBot.create(:user) } + let!(:comment) { FactoryBot.create(:comment, user: FactoryBot.create(:user), answer: a) } + + before do + sign_in user + end + + it "does not show the delete option" do + html = Nokogiri::HTML.parse(rendered) + selector = %(li.comment[data-comment-id="#{comment.id}"] .btn-group a[data-action="ab-comment-destroy"]) + expect(html.css(selector)).to be_empty + end + end + + context "containing a comment with smiles" do + let(:comment_author) { FactoryBot.create(:user) } + let(:comment) { FactoryBot.create(:comment, answer: a, user: comment_author) } + let(:other_comment) { FactoryBot.create(:comment, answer: a, user: comment_author) } + + before do + 5.times do + user = FactoryBot.create(:user) + user.smile comment + end + + User.last.smile other_comment + end + + it "shows the correct number of smiles" do + html = Nokogiri::HTML.parse(rendered) + selector = %(li.comment[data-comment-id="#{comment.id}"] button[data-action="smile"]>span) + expect(html.css(selector).text).to eq("5") + end + end + + context "containing a comment you've smiled" do + let(:user) { FactoryBot.create(:user) } + let!(:comment) { FactoryBot.create(:comment, user: FactoryBot.create(:user), answer: a) } + + before do + sign_in user + user.smile comment + end + + it "displays the comment as smiled" do + html = Nokogiri::HTML.parse(rendered) + selector = %(li.comment[data-comment-id="#{comment.id}"] button[data-action="unsmile"]) + expect(html.css(selector)).to_not be_empty + end + end +end From 9563a586c27809898748c27f0c11b92d10456fda Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Sun, 7 May 2023 17:33:46 +0200 Subject: [PATCH 058/590] Appease the dog overlords (mostly) --- app/controllers/ajax/comment_controller.rb | 4 ++-- app/controllers/comment_controller.rb | 2 +- spec/views/answerbox/_comments.html.haml_spec.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/ajax/comment_controller.rb b/app/controllers/ajax/comment_controller.rb index c2ef3341..c7264464 100644 --- a/app/controllers/ajax/comment_controller.rb +++ b/app/controllers/ajax/comment_controller.rb @@ -14,12 +14,12 @@ class Ajax::CommentController < AjaxController return end - comments = Comment.where(answer:).includes([{user: :profile}, :smiles]) + comments = Comment.where(answer:).includes([{ user: :profile }, :smiles]) @response[:status] = :okay @response[:message] = t(".success") @response[:success] = true - @response[:render] = render_to_string(partial: 'answerbox/comments', locals: { a: answer, comments: }) + @response[:render] = render_to_string(partial: "answerbox/comments", locals: { a: answer, comments: }) @response[:count] = answer.comment_count end diff --git a/app/controllers/comment_controller.rb b/app/controllers/comment_controller.rb index 0b61f2eb..d8b9ea6f 100644 --- a/app/controllers/comment_controller.rb +++ b/app/controllers/comment_controller.rb @@ -3,7 +3,7 @@ class CommentController < ApplicationController def index answer = Answer.find(params[:id]) - @comments = Comment.where(answer:).includes([{user: :profile}, :smiles]) + @comments = Comment.where(answer:).includes([{ user: :profile }, :smiles]) render "index", locals: { a: answer } end diff --git a/spec/views/answerbox/_comments.html.haml_spec.rb b/spec/views/answerbox/_comments.html.haml_spec.rb index 90090069..3af138d6 100644 --- a/spec/views/answerbox/_comments.html.haml_spec.rb +++ b/spec/views/answerbox/_comments.html.haml_spec.rb @@ -5,7 +5,7 @@ require "rails_helper" describe "answerbox/_comments.html.haml", type: :view do subject(:rendered) do render partial: "answerbox/comments", locals: { - comments:, a: + comments:, a:, } end From 81b271ab03737c78a811b2326e24c912d2cb1996 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Wed, 13 Sep 2023 23:21:59 +0100 Subject: [PATCH 059/590] Move reactions to separate view/endpoint --- app/controllers/reaction_controller.rb | 9 ++++++ app/views/application/_answerbox.html.haml | 4 +++ app/views/comment/index.html.haml | 1 - app/views/reaction/index.html.haml | 2 ++ config/routes.rb | 1 + spec/controllers/reaction_controller_spec.rb | 34 ++++++++++++++++++++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 app/controllers/reaction_controller.rb create mode 100644 app/views/reaction/index.html.haml create mode 100644 spec/controllers/reaction_controller_spec.rb diff --git a/app/controllers/reaction_controller.rb b/app/controllers/reaction_controller.rb new file mode 100644 index 00000000..c6df6000 --- /dev/null +++ b/app/controllers/reaction_controller.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class ReactionController < ApplicationController + def index + answer = Answer.includes([smiles: { user: :profile }]).find(params[:id]) + + render "index", locals: { a: answer } + end +end diff --git a/app/views/application/_answerbox.html.haml b/app/views/application/_answerbox.html.haml index c6236f3c..4524f405 100644 --- a/app/views/application/_answerbox.html.haml +++ b/app/views/application/_answerbox.html.haml @@ -35,6 +35,10 @@ .col-md-6.d-md-flex.answerbox__actions = render "answerbox/actions", a:, display_all:, subscribed_answer_ids: .card-footer{ id: "ab-comments-section-#{a.id}", class: display_all.nil? ? "d-none" : nil } + = turbo_frame_tag("ab-reactions-list-#{a.id}", src: reactions_path(a.question, a), loading: :lazy) do + .d-flex.smiles + .flex-shrink-0.me-1 + %i.fa.fa-smile-o = turbo_frame_tag("ab-comments-list-#{a.id}", src: comments_path(a.question, a), loading: :lazy) do .d-flex.justify-content-center .spinner-border{ role: :status } diff --git a/app/views/comment/index.html.haml b/app/views/comment/index.html.haml index 52cad691..e5334203 100644 --- a/app/views/comment/index.html.haml +++ b/app/views/comment/index.html.haml @@ -1,3 +1,2 @@ = turbo_frame_tag "ab-comments-list-#{a.id}" do - %div{ id: "ab-smiles-#{a.id}" }= render "answerbox/smiles", a: %div{ id: "ab-comments-#{a.id}" }= render "answerbox/comments", a:, comments: @comments diff --git a/app/views/reaction/index.html.haml b/app/views/reaction/index.html.haml new file mode 100644 index 00000000..b717a281 --- /dev/null +++ b/app/views/reaction/index.html.haml @@ -0,0 +1,2 @@ += turbo_frame_tag "ab-reactions-list-#{a.id}" do + %div{ id: "ab-smiles-#{a.id}" }= render "answerbox/smiles", a: diff --git a/config/routes.rb b/config/routes.rb index 85fc5a6e..e5fcf899 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -154,6 +154,7 @@ Rails.application.routes.draw do post "/@:username/a/:id/pin", to: "answer#pin", as: :pin_answer delete "/@:username/a/:id/pin", to: "answer#unpin", as: :unpin_answer get "/@:username/a/:id/comments", to: "comment#index", as: :comments + get "/@:username/a/:id/reactions", to: "reaction#index", as: :reactions get "/@:username/q/:id", to: "question#show", as: :question get "/@:username/followers", to: "user#followers", as: :show_user_followers get "/@:username/followings", to: "user#followings", as: :show_user_followings diff --git a/spec/controllers/reaction_controller_spec.rb b/spec/controllers/reaction_controller_spec.rb new file mode 100644 index 00000000..1b76617f --- /dev/null +++ b/spec/controllers/reaction_controller_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe ReactionController, type: :controller do + describe "#index" do + shared_examples_for "succeeds" do + it "returns the correct response" do + subject + expect(response).to have_rendered("reaction/index") + expect(response).to have_http_status(200) + end + end + + subject { get :index, params: { username: answer_author.screen_name, id: answer.id } } + + let(:answer_author) { FactoryBot.create(:user) } + let(:answer) { FactoryBot.create(:answer, user: answer_author) } + let!(:reactees) { FactoryBot.create_list(:user, num_comments) } + + [0, 1, 5, 30].each do |num_comments| + context "#{num_comments} reactions" do + let(:num_comments) { num_comments } + + before do + reactees.each { _1.smile(answer) } + end + + include_examples "succeeds" + end + end + + end +end From ed664c9580b412c47e7b0b90a499e7c9fc29b9d7 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Thu, 14 Sep 2023 16:37:11 +0100 Subject: [PATCH 060/590] Add view tests for smiles list partial --- .../views/answerbox/_smiles.html.haml_spec.rb | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 spec/views/answerbox/_smiles.html.haml_spec.rb diff --git a/spec/views/answerbox/_smiles.html.haml_spec.rb b/spec/views/answerbox/_smiles.html.haml_spec.rb new file mode 100644 index 00000000..5530d648 --- /dev/null +++ b/spec/views/answerbox/_smiles.html.haml_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe "answerbox/_smiles.html.haml", type: :view do + subject(:rendered) do + render partial: "answerbox/smiles", locals: { a: } + end + + let(:a) { FactoryBot.create(:answer, user: FactoryBot.create(:user)) } + + context "no reactions" do + it "shows an empty list" do + expect(rendered).to match("No one smiled this yet.") + end + end + + context "reactions are present" do + let!(:reactions) { FactoryBot.create_list(:smile, 5, parent: a) } + + it "shows a list of users" do + html = Nokogiri::HTML.parse(rendered) + selector = %(.smiles a) + reaction_elements = html.css(selector) + expect(reaction_elements.size).to eq(5) + end + end +end From b4a36c6617053ef87d9339dfc11cbf90ea8b5cdf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 09:06:58 +0000 Subject: [PATCH 061/590] Bump sass from 1.69.0 to 1.69.3 Bumps [sass](https://github.com/sass/dart-sass) from 1.69.0 to 1.69.3. - [Release notes](https://github.com/sass/dart-sass/releases) - [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md) - [Commits](https://github.com/sass/dart-sass/compare/1.69.0...1.69.3) --- updated-dependencies: - dependency-name: sass dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7bc670e2..4598486a 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "croppr": "^2.3.1", "i18n-js": "^4.0", "js-cookie": "2.2.1", - "sass": "^1.69.0", + "sass": "^1.69.3", "sweetalert": "1.1.3", "toastify-js": "^1.12.0", "typescript": "^5.2.2" diff --git a/yarn.lock b/yarn.lock index 21b7897a..932f95b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2268,10 +2268,10 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -sass@^1.69.0: - version "1.69.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.0.tgz#5195075371c239ed556280cf2f5944d234f42679" - integrity sha512-l3bbFpfTOGgQZCLU/gvm1lbsQ5mC/WnLz3djL2v4WCJBDrWm58PO+jgngcGRNnKUh6wSsdm50YaovTqskZ0xDQ== +sass@^1.69.3: + version "1.69.3" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.3.tgz#f8a0c488697e6419519834a13335e7b65a609c11" + integrity sha512-X99+a2iGdXkdWn1akFPs0ZmelUzyAQfvqYc2P/MPTrJRuIRoTffGzT9W9nFqG00S+c8hXzVmgxhUuHFdrwxkhQ== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" From b4231491b31333b96360ca156f2f848261839815 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 09:07:20 +0000 Subject: [PATCH 062/590] Bump @github/hotkey from 2.0.1 to 2.1.1 Bumps [@github/hotkey](https://github.com/github/hotkey) from 2.0.1 to 2.1.1. - [Release notes](https://github.com/github/hotkey/releases) - [Commits](https://github.com/github/hotkey/compare/v2.0.1...v2.1.1) --- updated-dependencies: - dependency-name: "@github/hotkey" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7bc670e2..e9734251 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "dependencies": { "@fontsource/lexend": "^4.5.15", "@fortawesome/fontawesome-free": "^6.4.2", - "@github/hotkey": "^2.0.1", + "@github/hotkey": "^2.1.1", "@hotwired/stimulus": "^3.2.2", "@hotwired/turbo-rails": "^7.3.0", "@melloware/coloris": "^0.21.1", diff --git a/yarn.lock b/yarn.lock index 21b7897a..b59d23e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -199,10 +199,10 @@ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.2.tgz#36b6a9cb5ffbecdf89815c94d0c0ffa489ac5ecb" integrity sha512-m5cPn3e2+FDCOgi1mz0RexTUvvQibBebOUlUlW0+YrMjDTPkiJ6VTKukA1GRsvRw+12KyJndNjj0O4AgTxm2Pg== -"@github/hotkey@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@github/hotkey/-/hotkey-2.0.1.tgz#24ad6b49313cee5b98368174eab16a4b53a08ec7" - integrity sha512-qKXjAJjtheJbf4ie3hi8IwrHWJZHB5qdojR6JGo6jvQNPpsdUbk/NIdU8sxu4PW41CjW80vfciDMu3MAP3j2Fg== +"@github/hotkey@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@github/hotkey/-/hotkey-2.1.1.tgz#0e1da799c7a43d719b21f740bc59107dec30ea3b" + integrity sha512-UPb3mbKQzw3uskbRu+jsJwhAP2lFhxH0vI799camXiNbV5q3w61VNGt3oX7yxn4HhC5V4S701NoOqGbosCJhiw== "@hotwired/stimulus@^3.2.2": version "3.2.2" From 83d2de1294f2ba192a38ebf3b46e3e84c74db099 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 09:57:00 +0000 Subject: [PATCH 063/590] Bump lograge from 0.13.0 to 0.14.0 Bumps [lograge](https://github.com/roidrage/lograge) from 0.13.0 to 0.14.0. - [Release notes](https://github.com/roidrage/lograge/releases) - [Changelog](https://github.com/roidrage/lograge/blob/master/CHANGELOG.md) - [Commits](https://github.com/roidrage/lograge/compare/v0.13.0...v0.14.0) --- updated-dependencies: - dependency-name: lograge dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 539ed2e2..b1b1ea16 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -238,12 +238,12 @@ GEM addressable (~> 2.7) letter_opener (1.8.1) launchy (>= 2.2, < 3) - lograge (0.13.0) + lograge (0.14.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.21.3) + loofah (2.21.4) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.7.1) From 29d6437b3ef73c44cdd25ceac71bdfc9620072f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 09:57:32 +0000 Subject: [PATCH 064/590] Bump bullet from 7.1.1 to 7.1.2 Bumps [bullet](https://github.com/flyerhzm/bullet) from 7.1.1 to 7.1.2. - [Changelog](https://github.com/flyerhzm/bullet/blob/main/CHANGELOG.md) - [Commits](https://github.com/flyerhzm/bullet/compare/7.1.1...7.1.2) --- updated-dependencies: - dependency-name: bullet dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 539ed2e2..6c7c40d8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,7 +100,7 @@ GEM actionpack (>= 5.2) activemodel (>= 5.2) builder (3.2.4) - bullet (7.1.1) + bullet (7.1.2) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) carrierwave (2.1.0) From 4ac8e6dd41991b23784fc08760054d9b3893ad79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 09:58:19 +0000 Subject: [PATCH 065/590] Bump net-imap from 0.4.0 to 0.4.1 Bumps [net-imap](https://github.com/ruby/net-imap) from 0.4.0 to 0.4.1. - [Release notes](https://github.com/ruby/net-imap/releases) - [Commits](https://github.com/ruby/net-imap/compare/v0.4.0...v0.4.1) --- updated-dependencies: - dependency-name: net-imap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 539ed2e2..b15527b8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -268,7 +268,7 @@ GEM connection_pool (~> 2.2) net-http2 (0.18.4) http-2 (~> 0.11) - net-imap (0.4.0) + net-imap (0.4.1) date net-protocol net-pop (0.1.2) From c1124fc94c9e13c50c1dd9ae62d0b7dcca24408b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 09:58:58 +0000 Subject: [PATCH 066/590] Bump devise from 4.9.2 to 4.9.3 Bumps [devise](https://github.com/heartcombo/devise) from 4.9.2 to 4.9.3. - [Release notes](https://github.com/heartcombo/devise/releases) - [Changelog](https://github.com/heartcombo/devise/blob/main/CHANGELOG.md) - [Commits](https://github.com/heartcombo/devise/compare/v4.9.2...v4.9.3) --- updated-dependencies: - dependency-name: devise dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 539ed2e2..123baa56 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -125,7 +125,7 @@ GEM database_cleaner-core (2.0.1) date (3.3.3) debug_inspector (1.1.0) - devise (4.9.2) + devise (4.9.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) @@ -243,7 +243,7 @@ GEM activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.21.3) + loofah (2.21.4) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.7.1) @@ -350,7 +350,7 @@ GEM regexp_parser (2.8.1) request_store (1.5.1) rack (>= 1.4) - responders (3.1.0) + responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) rexml (3.2.6) From d4eabbe05f08d0f24a52738ebce084e11e5136ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 09:59:48 +0000 Subject: [PATCH 067/590] Bump rubocop from 1.56.4 to 1.57.1 Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.56.4 to 1.57.1. - [Release notes](https://github.com/rubocop/rubocop/releases) - [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop/rubocop/compare/v1.56.4...v1.57.1) --- updated-dependencies: - dependency-name: rubocop dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 02cf3416..6366c330 100644 --- a/Gemfile +++ b/Gemfile @@ -91,7 +91,7 @@ group :development, :test do gem "rspec-mocks" gem "rspec-rails", "~> 6.0" gem "rspec-sidekiq", "~> 4.0", require: false - gem "rubocop", "~> 1.56" + gem "rubocop", "~> 1.57" gem "rubocop-rails", "~> 2.21" gem "shoulda-matchers", "~> 5.3" gem "simplecov", require: false diff --git a/Gemfile.lock b/Gemfile.lock index 539ed2e2..aa53bb9b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -347,7 +347,7 @@ GEM rake (13.0.6) redcarpet (3.6.0) redis (4.8.0) - regexp_parser (2.8.1) + regexp_parser (2.8.2) request_store (1.5.1) rack (>= 1.4) responders (3.1.0) @@ -396,12 +396,12 @@ GEM rspec-mocks (~> 3.0) sidekiq (>= 5, < 8) rspec-support (3.12.1) - rubocop (1.56.4) + rubocop (1.57.1) base64 (~> 0.1.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.3) + parser (>= 3.2.2.4) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) @@ -561,7 +561,7 @@ DEPENDENCIES rspec-mocks rspec-rails (~> 6.0) rspec-sidekiq (~> 4.0) - rubocop (~> 1.56) + rubocop (~> 1.57) rubocop-rails (~> 2.21) rubyzip (~> 2.3) sanitize From b706e6e6dc8b0fc5594f39a753e52f70be9bdd20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 10:04:44 +0000 Subject: [PATCH 068/590] Bump turbo-rails from 1.4.0 to 1.5.0 Bumps [turbo-rails](https://github.com/hotwired/turbo-rails) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/hotwired/turbo-rails/releases) - [Commits](https://github.com/hotwired/turbo-rails/compare/v1.4.0...v1.5.0) --- updated-dependencies: - dependency-name: turbo-rails dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 539ed2e2..fb6aaf62 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -189,8 +189,8 @@ GEM nokogiri (>= 1.5.11, < 2.0.0) formatador (1.1.0) glob (0.3.1) - globalid (1.1.0) - activesupport (>= 5.0) + globalid (1.2.1) + activesupport (>= 6.1) haml (6.1.4) temple (>= 0.8.2) thor @@ -243,7 +243,7 @@ GEM activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.21.3) + loofah (2.21.4) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.7.1) @@ -471,7 +471,7 @@ GEM tldv (0.1.0) tldv-data (~> 1.0) tldv-data (1.0.2023031000) - turbo-rails (1.4.0) + turbo-rails (1.5.0) actionpack (>= 6.0.0) activejob (>= 6.0.0) railties (>= 6.0.0) From 6b6614ba1367d1c072941e54a532a30dd7c46957 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 10:41:38 +0000 Subject: [PATCH 069/590] Bump haml from 6.1.4 to 6.2.3 Bumps [haml](https://github.com/haml/haml) from 6.1.4 to 6.2.3. - [Release notes](https://github.com/haml/haml/releases) - [Changelog](https://github.com/haml/haml/blob/main/CHANGELOG.md) - [Commits](https://github.com/haml/haml/compare/v6.1.4...v6.2.3) --- updated-dependencies: - dependency-name: haml dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 02cf3416..bad5a989 100644 --- a/Gemfile +++ b/Gemfile @@ -30,7 +30,7 @@ gem "devise-i18n" gem "fog-aws" gem "fog-core" gem "fog-local" -gem "haml", "~> 6.1" +gem "haml", "~> 6.2" gem "hcaptcha", git: "https://github.com/raccube/hcaptcha", ref: "fix/flash-in-turbo-streams" gem "mini_magick" gem "oj" diff --git a/Gemfile.lock b/Gemfile.lock index e6ed540b..d24d93b4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -191,7 +191,7 @@ GEM glob (0.3.1) globalid (1.2.1) activesupport (>= 6.1) - haml (6.1.4) + haml (6.2.3) temple (>= 0.8.2) thor tilt @@ -524,7 +524,7 @@ DEPENDENCIES fog-aws fog-core fog-local - haml (~> 6.1) + haml (~> 6.2) haml_lint hcaptcha! httparty From 26e1a9df1a5ae45d43288435b36eb1f309940a79 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 16 Oct 2023 13:33:57 +0200 Subject: [PATCH 070/590] Suggest pure iPhone two factor capabilities --- .../otp_authentication/_totp_setup.html.haml | 6 ++++++ config/locales/views.en.yml | 2 ++ 2 files changed, 8 insertions(+) diff --git a/app/views/settings/two_factor_authentication/otp_authentication/_totp_setup.html.haml b/app/views/settings/two_factor_authentication/otp_authentication/_totp_setup.html.haml index 6c707a48..85b1630f 100644 --- a/app/views/settings/two_factor_authentication/otp_authentication/_totp_setup.html.haml +++ b/app/views/settings/two_factor_authentication/otp_authentication/_totp_setup.html.haml @@ -36,6 +36,12 @@ %a{ href: "https://apps.apple.com/gb/app/microsoft-authenticator/id983156458" }= t(".source.app_store") %li.list-inline-item %a{ href: "https://play.google.com/store/apps/details?id=com.azure.authenticator" }= t(".source.google_play") + %li + %i.fa.fa-apple + = t(".app.iphone") + %ul.list-inline + %li.list-inline-item + %a{ href: "https://support.apple.com/en-gb/guide/iphone/ipha6173c19f/ios" }= t(".source.apple_support") %p= t(".setup_qr", app_name: APP_CONFIG['site_name']) = f.text_field :otp_validation, class: "totp-setup__code-field", inputmode: :numeric, label: t(".otp_validation"), autofocus: true = f.primary diff --git a/config/locales/views.en.yml b/config/locales/views.en.yml index 20994bce..ed2280b5 100644 --- a/config/locales/views.en.yml +++ b/config/locales/views.en.yml @@ -492,7 +492,9 @@ en: aegis: "Aegis Authenticator for Android" strongbox: "Strongbox Authenticator for iOS" microsoft: "Microsoft Authenticator" + iphone: "iPhone (Passwords/Camera)" source: + apple_support: "Apple Support" app_store: "App Store" fdroid: "F-Droid" google_play: "Google Play" From 6aee2baa45462c6c205e49e3530e9cd06e88e69e Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 16 Oct 2023 15:27:07 +0200 Subject: [PATCH 071/590] Name label iOS instead of iPhone --- .../otp_authentication/_totp_setup.html.haml | 2 +- config/locales/views.en.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/settings/two_factor_authentication/otp_authentication/_totp_setup.html.haml b/app/views/settings/two_factor_authentication/otp_authentication/_totp_setup.html.haml index 85b1630f..4388bf05 100644 --- a/app/views/settings/two_factor_authentication/otp_authentication/_totp_setup.html.haml +++ b/app/views/settings/two_factor_authentication/otp_authentication/_totp_setup.html.haml @@ -38,7 +38,7 @@ %a{ href: "https://play.google.com/store/apps/details?id=com.azure.authenticator" }= t(".source.google_play") %li %i.fa.fa-apple - = t(".app.iphone") + = t(".app.ios") %ul.list-inline %li.list-inline-item %a{ href: "https://support.apple.com/en-gb/guide/iphone/ipha6173c19f/ios" }= t(".source.apple_support") diff --git a/config/locales/views.en.yml b/config/locales/views.en.yml index ed2280b5..5b909fde 100644 --- a/config/locales/views.en.yml +++ b/config/locales/views.en.yml @@ -492,7 +492,7 @@ en: aegis: "Aegis Authenticator for Android" strongbox: "Strongbox Authenticator for iOS" microsoft: "Microsoft Authenticator" - iphone: "iPhone (Passwords/Camera)" + ios: "iOS (Passwords/Camera)" source: apple_support: "Apple Support" app_store: "App Store" From e4c054ad92e06e0c232fa8ac7890323a02009351 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Tue, 17 Oct 2023 19:52:00 +0200 Subject: [PATCH 072/590] Set rel=me on website link in profiles --- app/views/user/_profile.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/user/_profile.html.haml b/app/views/user/_profile.html.haml index 8ceffb5c..7afb27f8 100644 --- a/app/views/user/_profile.html.haml +++ b/app/views/user/_profile.html.haml @@ -32,7 +32,7 @@ - unless user.profile.website.blank? .profile__website %i.fa.fa-fw.fa-globe - %a{ href: user.profile.website, target: "_blank", rel: "nofollow" }= user.profile.display_website + %a{ href: user.profile.website, target: "_blank", rel: "me nofollow" }= user.profile.display_website - unless user.profile.location.blank? .profile__location %i.fa.fa-fw.fa-location-arrow From 3feb827b16b187b38316cf2201e74399feb714e1 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 16 Oct 2023 15:02:57 +0200 Subject: [PATCH 073/590] Add support for sharing dialog in inbox answer sharing --- .../stylesheets/components/_inbox-entry.scss | 6 +++ .../controllers/inbox_sharing_controller.ts | 4 +- .../controllers/share_controller.ts | 42 +++++++++++++++++++ .../features/inbox/entry/answer.ts | 5 +++ .../retrospring/initializers/stimulus.ts | 2 + app/views/inbox/_entry.html.haml | 3 ++ 6 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 app/javascript/retrospring/controllers/share_controller.ts diff --git a/app/assets/stylesheets/components/_inbox-entry.scss b/app/assets/stylesheets/components/_inbox-entry.scss index a56875cd..b10ee20b 100644 --- a/app/assets/stylesheets/components/_inbox-entry.scss +++ b/app/assets/stylesheets/components/_inbox-entry.scss @@ -57,3 +57,9 @@ position: relative; } } + +body:not(.cap-web-share) { + [data-controller="share"] { + display: none; + } +} diff --git a/app/javascript/retrospring/controllers/inbox_sharing_controller.ts b/app/javascript/retrospring/controllers/inbox_sharing_controller.ts index 6d0218b1..d087d62d 100644 --- a/app/javascript/retrospring/controllers/inbox_sharing_controller.ts +++ b/app/javascript/retrospring/controllers/inbox_sharing_controller.ts @@ -1,12 +1,13 @@ import { Controller } from '@hotwired/stimulus'; export default class extends Controller { - static targets = ['twitter', 'tumblr', 'telegram', 'custom']; + static targets = ['twitter', 'tumblr', 'telegram', 'other', 'custom']; declare readonly twitterTarget: HTMLAnchorElement; declare readonly tumblrTarget: HTMLAnchorElement; declare readonly telegramTarget: HTMLAnchorElement; declare readonly customTarget: HTMLAnchorElement; + declare readonly otherTarget: HTMLButtonElement; declare readonly hasCustomTarget: boolean; static values = { @@ -22,6 +23,7 @@ export default class extends Controller { this.twitterTarget.addEventListener('click', () => this.close()); this.tumblrTarget.addEventListener('click', () => this.close()); this.telegramTarget.addEventListener('click', () => this.close()); + this.otherTarget.addEventListener('click', () => this.close()); if (this.hasCustomTarget) { this.customTarget.addEventListener('click', () => this.close()); diff --git a/app/javascript/retrospring/controllers/share_controller.ts b/app/javascript/retrospring/controllers/share_controller.ts new file mode 100644 index 00000000..e9e8d250 --- /dev/null +++ b/app/javascript/retrospring/controllers/share_controller.ts @@ -0,0 +1,42 @@ +import { Controller } from '@hotwired/stimulus'; + +export default class extends Controller { + static values = { + url: String, + text: String, + title: String + }; + + declare readonly urlValue: string; + declare readonly textValue: string; + declare readonly titleValue: string; + + share() { + let shareConfiguration = {}; + + if (this.urlValue.length >= 1) { + shareConfiguration = { + ...shareConfiguration, + ...{ url: this.urlValue } + }; + } + + if (this.textValue.length >= 1) { + shareConfiguration = { + ...shareConfiguration, + ...{ text: this.textValue } + }; + } + + if (this.titleValue.length >= 1) { + shareConfiguration = { + ...shareConfiguration, + ...{ title: this.titleValue } + }; + } + + navigator.share(shareConfiguration).then(() => { + this.element.dispatchEvent(new CustomEvent('retrospring:shared')); + }); + } +} diff --git a/app/javascript/retrospring/features/inbox/entry/answer.ts b/app/javascript/retrospring/features/inbox/entry/answer.ts index 93b0cefc..77440d17 100644 --- a/app/javascript/retrospring/features/inbox/entry/answer.ts +++ b/app/javascript/retrospring/features/inbox/entry/answer.ts @@ -34,6 +34,11 @@ export function answerEntryHandler(event: Event): void { if (sharing != null) { sharing.dataset.inboxSharingConfigValue = JSON.stringify(data.sharing); } + + const shareButton = inboxEntry.querySelector('[data-controller="share"]'); + if (shareButton != null) { + shareButton.dataset.shareTextValue = decodeURIComponent(data.sharing.custom).replaceAll('+', ' '); + } else { (inboxEntry as HTMLElement).remove(); } diff --git a/app/javascript/retrospring/initializers/stimulus.ts b/app/javascript/retrospring/initializers/stimulus.ts index aee44e36..79116e3e 100644 --- a/app/javascript/retrospring/initializers/stimulus.ts +++ b/app/javascript/retrospring/initializers/stimulus.ts @@ -13,6 +13,7 @@ import InboxSharingController from "retrospring/controllers/inbox_sharing_contro import ToastController from "retrospring/controllers/toast_controller"; import PwaBadgeController from "retrospring/controllers/pwa_badge_controller"; import NavigationController from "retrospring/controllers/navigation_controller"; +import ShareController from "retrospring/controllers/share_controller"; /** * This module sets up Stimulus and our controllers @@ -37,4 +38,5 @@ export default function (): void { window['Stimulus'].register('navigation', NavigationController); window['Stimulus'].register('theme', ThemeController); window['Stimulus'].register('toast', ToastController); + window['Stimulus'].register('share', ShareController); } diff --git a/app/views/inbox/_entry.html.haml b/app/views/inbox/_entry.html.haml index eb92ed7d..1d37c711 100644 --- a/app/views/inbox/_entry.html.haml +++ b/app/views/inbox/_entry.html.haml @@ -52,6 +52,9 @@ %a.btn.btn-primary{ href: "#", data: { inbox_sharing_target: "telegram" }, target: "_blank" } %i.fab.fa-telegram.fa-fw Telegram + %button.btn.btn-primary{ data: { controller: "share", action: "share#share", inbox_sharing_target: "other" } } + %i.fa.fa-fw.fa-share-alt + = t("actions.share.other") - if current_user.sharing_custom_url.present? %a.btn.btn-primary{ href: current_user.sharing_custom_url, data: { inbox_sharing_target: "custom" }, target: "_blank" } = current_user.display_sharing_custom_url From 5ccdd9bbc2f1a3fef7f3e232c484e71d764276d2 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 16 Oct 2023 15:19:45 +0200 Subject: [PATCH 074/590] Remove answerbox-specific sharing feature --- app/assets/stylesheets/components/_answerbox.scss | 6 ------ .../retrospring/features/answerbox/index.ts | 2 -- .../retrospring/features/answerbox/share.ts | 12 ------------ 3 files changed, 20 deletions(-) delete mode 100644 app/javascript/retrospring/features/answerbox/share.ts diff --git a/app/assets/stylesheets/components/_answerbox.scss b/app/assets/stylesheets/components/_answerbox.scss index adb1b732..e0e3936f 100644 --- a/app/assets/stylesheets/components/_answerbox.scss +++ b/app/assets/stylesheets/components/_answerbox.scss @@ -97,9 +97,3 @@ display: inline; } } - -body:not(.cap-web-share) { - [name="ab-share"] { - display: none; - } -} diff --git a/app/javascript/retrospring/features/answerbox/index.ts b/app/javascript/retrospring/features/answerbox/index.ts index b0a3a897..61dc7edc 100644 --- a/app/javascript/retrospring/features/answerbox/index.ts +++ b/app/javascript/retrospring/features/answerbox/index.ts @@ -2,13 +2,11 @@ import registerEvents from 'utilities/registerEvents'; import registerAnswerboxCommentEvents from './comment'; import { answerboxDestroyHandler } from './destroy'; import { answerboxReportHandler } from './report'; -import { shareEventHandler } from './share'; import { answerboxSmileHandler } from './smile'; import { answerboxSubscribeHandler } from './subscribe'; export default (): void => { registerEvents([ - { type: 'click', target: '[name=ab-share]', handler: shareEventHandler, global: true }, { type: 'click', target: '[data-action=ab-submarine]', handler: answerboxSubscribeHandler, global: true }, { type: 'click', target: '[data-action=ab-report]', handler: answerboxReportHandler, global: true }, { type: 'click', target: '[data-action=ab-destroy]', handler: answerboxDestroyHandler, global: true }, diff --git a/app/javascript/retrospring/features/answerbox/share.ts b/app/javascript/retrospring/features/answerbox/share.ts deleted file mode 100644 index 9018550e..00000000 --- a/app/javascript/retrospring/features/answerbox/share.ts +++ /dev/null @@ -1,12 +0,0 @@ -import noop from 'utilities/noop'; - -export function shareEventHandler(event: Event): void { - event.preventDefault(); - const answerbox = (event.target as HTMLElement).closest('.answerbox'); - - navigator.share({ - url: answerbox.querySelector('.answerbox__answer-date > a, a.answerbox__permalink').href - }) - .then(noop) - .catch(noop) -} From 9f999189cd87eed3291efb24bd5ae3a543719a69 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 16 Oct 2023 15:20:04 +0200 Subject: [PATCH 075/590] Add Stimulus sharing feature to answerboxes --- app/helpers/social_helper.rb | 9 +++++++++ app/views/actions/_share.html.haml | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/helpers/social_helper.rb b/app/helpers/social_helper.rb index e1ffe35f..b8ce3b9d 100644 --- a/app/helpers/social_helper.rb +++ b/app/helpers/social_helper.rb @@ -4,4 +4,13 @@ module SocialHelper include SocialHelper::TwitterMethods include SocialHelper::TumblrMethods include SocialHelper::TelegramMethods + + def answer_share_url(answer) + answer_url( + id: answer.id, + username: answer.user.screen_name, + host: APP_CONFIG["hostname"], + protocol: (APP_CONFIG["https"] ? :https : :http) + ) + end end diff --git a/app/views/actions/_share.html.haml b/app/views/actions/_share.html.haml index 65daacc2..5fc3c26b 100644 --- a/app/views/actions/_share.html.haml +++ b/app/views/actions/_share.html.haml @@ -8,5 +8,5 @@ %a.dropdown-item{ href: telegram_share_url(answer), target: "_blank" } %i.fa.fa-fw.fa-telegram = t(".telegram") - %a.dropdown-item{ href: "#", name: "ab-share" } + %a.dropdown-item{ href: "#", data: { controller: :share, action: "share#share", share_url_value: answer_share_url(answer) } } = t(".other") From e74e233548f6cb4804ed9551e4272276d1f9264d Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 16 Oct 2023 15:20:24 +0200 Subject: [PATCH 076/590] Add spec for `answer_share_url` --- spec/helpers/social_helper_spec.rb | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 spec/helpers/social_helper_spec.rb diff --git a/spec/helpers/social_helper_spec.rb b/spec/helpers/social_helper_spec.rb new file mode 100644 index 00000000..6841cdef --- /dev/null +++ b/spec/helpers/social_helper_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe SocialHelper, type: :helper do + let(:user) { FactoryBot.create(:user) } + let(:answer) do + FactoryBot.create( + :answer, + user:, + content: "this is an answer\nwith multiple lines\nand **FORMATTING**", + question_content: "this is a question .... or is it?" + ) + end + + before do + stub_const("APP_CONFIG", { + "hostname" => "example.com", + "https" => true, + "items_per_page" => 5, + }) + end + + describe "#answer_share_url" do + subject { answer_share_url(answer) } + + it "returns a proper share link" do + expect(subject).to eq(<<~URL.strip) + https://example.com/@#{answer.user.screen_name}/a/#{answer.id} + URL + end + end +end From af3caf9be1509b2a0716dea386427d5053b0dd05 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 16 Oct 2023 15:24:18 +0200 Subject: [PATCH 077/590] Fix stylelint nit --- app/assets/stylesheets/components/_inbox-entry.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/components/_inbox-entry.scss b/app/assets/stylesheets/components/_inbox-entry.scss index b10ee20b..3583a3f3 100644 --- a/app/assets/stylesheets/components/_inbox-entry.scss +++ b/app/assets/stylesheets/components/_inbox-entry.scss @@ -59,6 +59,7 @@ } body:not(.cap-web-share) { + [data-controller="share"] { display: none; } From 5f0fed8c94ae7a27ab4efcab084474c68f1e20cb Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 16 Oct 2023 15:32:48 +0200 Subject: [PATCH 078/590] Fix rubocop nits --- app/helpers/social_helper.rb | 2 +- spec/helpers/social_helper_spec.rb | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/helpers/social_helper.rb b/app/helpers/social_helper.rb index b8ce3b9d..c4d8b329 100644 --- a/app/helpers/social_helper.rb +++ b/app/helpers/social_helper.rb @@ -10,7 +10,7 @@ module SocialHelper id: answer.id, username: answer.user.screen_name, host: APP_CONFIG["hostname"], - protocol: (APP_CONFIG["https"] ? :https : :http) + protocol: (APP_CONFIG["https"] ? :https : :http), ) end end diff --git a/spec/helpers/social_helper_spec.rb b/spec/helpers/social_helper_spec.rb index 6841cdef..1c165eb0 100644 --- a/spec/helpers/social_helper_spec.rb +++ b/spec/helpers/social_helper_spec.rb @@ -9,7 +9,7 @@ describe SocialHelper, type: :helper do :answer, user:, content: "this is an answer\nwith multiple lines\nand **FORMATTING**", - question_content: "this is a question .... or is it?" + question_content: "this is a question .... or is it?", ) end @@ -18,7 +18,8 @@ describe SocialHelper, type: :helper do "hostname" => "example.com", "https" => true, "items_per_page" => 5, - }) + }, + ) end describe "#answer_share_url" do From 0f0f3ae0c64bd193f8fe7790bbb3b68df227fa32 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 16 Oct 2023 15:33:02 +0200 Subject: [PATCH 079/590] Fix sharing view spec test case --- spec/views/actions/_share.html.haml_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/views/actions/_share.html.haml_spec.rb b/spec/views/actions/_share.html.haml_spec.rb index 16153d1c..f3dfc49f 100644 --- a/spec/views/actions/_share.html.haml_spec.rb +++ b/spec/views/actions/_share.html.haml_spec.rb @@ -24,6 +24,6 @@ describe "actions/_share.html.haml", type: :view do end it "has a dropdown item to share to anywhere else" do - expect(rendered).to have_css(%(a.dropdown-item[name="ab-share"])) + expect(rendered).to have_css(%(a.dropdown-item[data-controller="share"])) end end From 87813d30057d29b67b2737f2d62f136e0c86641a Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Mon, 16 Oct 2023 19:38:20 +0200 Subject: [PATCH 080/590] Fix sharing condition --- .../retrospring/features/inbox/entry/answer.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/javascript/retrospring/features/inbox/entry/answer.ts b/app/javascript/retrospring/features/inbox/entry/answer.ts index 77440d17..c515dc30 100644 --- a/app/javascript/retrospring/features/inbox/entry/answer.ts +++ b/app/javascript/retrospring/features/inbox/entry/answer.ts @@ -30,15 +30,15 @@ export function answerEntryHandler(event: Event): void { updateDeleteButton(false); showNotification(data.message); - const sharing = inboxEntry.querySelector('.inbox-entry__sharing'); - if (sharing != null) { - sharing.dataset.inboxSharingConfigValue = JSON.stringify(data.sharing); - } - const shareButton = inboxEntry.querySelector('[data-controller="share"]'); if (shareButton != null) { shareButton.dataset.shareTextValue = decodeURIComponent(data.sharing.custom).replaceAll('+', ' '); } + + const sharing = inboxEntry.querySelector('.inbox-entry__sharing'); + if (sharing != null) { + sharing.dataset.inboxSharingConfigValue = JSON.stringify(data.sharing); + } else { (inboxEntry as HTMLElement).remove(); } From 3aa18ef7c746b5694dd48f132945a7db8ba29379 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Tue, 17 Oct 2023 20:09:12 +0200 Subject: [PATCH 081/590] only initialize service workers if they are available --- app/javascript/retrospring/initializers/serviceWorker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/javascript/retrospring/initializers/serviceWorker.ts b/app/javascript/retrospring/initializers/serviceWorker.ts index fdf5f1ff..e5dfb081 100644 --- a/app/javascript/retrospring/initializers/serviceWorker.ts +++ b/app/javascript/retrospring/initializers/serviceWorker.ts @@ -1,3 +1,5 @@ export default function (): void { - navigator.serviceWorker.register("/service_worker.js", { scope: "/" }); + if ('serviceWorker' in navigator) { + navigator.serviceWorker.register("/service_worker.js", { scope: "/" }); + } } From 97a826be332bca3f642eaff7fb559b6cb757dcb6 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Tue, 17 Oct 2023 20:22:26 +0200 Subject: [PATCH 082/590] Bump version to 2023.1017.0 --- lib/retrospring/version.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/retrospring/version.rb b/lib/retrospring/version.rb index 7a679293..6483f4e9 100644 --- a/lib/retrospring/version.rb +++ b/lib/retrospring/version.rb @@ -15,9 +15,9 @@ module Retrospring def year = 2023 - def month = 9 + def month = 10 - def day = 1 + def day = 17 def patch = 0 From fce3d7c587cf57c291f70f1e09b8aa0e261bd54a Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Tue, 17 Oct 2023 21:48:49 +0200 Subject: [PATCH 083/590] Disable Turbo on registration form --- app/views/devise/registrations/new.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 698e63b9..d0fa29d6 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -5,7 +5,7 @@ .card.mt-3 .card-body %h1= t(".title") - = bootstrap_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| + = bootstrap_form_for(resource, as: resource_name, url: registration_path(resource_name), data: { turbo: false }) do |f| = render "devise/shared/error_messages", resource: resource = render "layouts/messages" From bdedd92817837a57377df020f48761d3484c3912 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Tue, 17 Oct 2023 21:51:18 +0200 Subject: [PATCH 084/590] Bump version to 2023.1017.1 --- lib/retrospring/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/retrospring/version.rb b/lib/retrospring/version.rb index 6483f4e9..9046c9d6 100644 --- a/lib/retrospring/version.rb +++ b/lib/retrospring/version.rb @@ -19,7 +19,7 @@ module Retrospring def day = 17 - def patch = 0 + def patch = 1 def suffix = "" From 4f1b6ca03e8b91221fb69af51fe36fb5d0217d91 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Tue, 17 Oct 2023 21:59:08 +0200 Subject: [PATCH 085/590] Allow setting extra hosts in development environments --- config/environments/development.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/environments/development.rb b/config/environments/development.rb index c2434c8c..bf96e5b2 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -75,6 +75,7 @@ Rails.application.configure do # Use an evented file watcher to asynchronously detect changes in source code, # routes, locales, etc. This feature depends on the listen gem. # config.file_watcher = ActiveSupport::EventedFileUpdateChecker + config.hosts += ENV["EXTRA_HOSTS"].split(':') if ENV["EXTRA_HOSTS"].present? end # For better_errors to work inside Docker we need From dda12956539b7ff5d00a5b827283a10cf58834f5 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Tue, 17 Oct 2023 21:59:37 +0200 Subject: [PATCH 086/590] Use Ruby 3.2.2 --- .docker/ruby/Dockerfile | 2 +- .ruby-version | 2 +- Containerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.docker/ruby/Dockerfile b/.docker/ruby/Dockerfile index 6e6e33d2..5cba21a9 100644 --- a/.docker/ruby/Dockerfile +++ b/.docker/ruby/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.1 +FROM ruby:3.2 USER root diff --git a/.ruby-version b/.ruby-version index ef538c28..be94e6f5 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.1.2 +3.2.2 diff --git a/Containerfile b/Containerfile index 249f7323..adc849a8 100644 --- a/Containerfile +++ b/Containerfile @@ -8,7 +8,7 @@ LABEL org.opencontainers.image.vendor="The Retrospring team" LABEL org.opencontainers.image.url="https://github.com/Retrospring/retrospring" ARG RETROSPRING_VERSION=2023.0131.1 -ARG RUBY_VERSION=3.1.2 +ARG RUBY_VERSION=3.2.2 ARG RUBY_INSTALL_VERSION=0.9.0 ARG BUNDLER_VERSION=2.3.18 From 3539c3264b2e7c1ff777342e442466230876b5e6 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek <6197148+raccube@users.noreply.github.com> Date: Wed, 18 Oct 2023 09:10:28 +0200 Subject: [PATCH 087/590] Bump ruby-install version to 0.9.2 Co-authored-by: Georg Gadinger --- Containerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Containerfile b/Containerfile index adc849a8..73044568 100644 --- a/Containerfile +++ b/Containerfile @@ -9,7 +9,7 @@ LABEL org.opencontainers.image.url="https://github.com/Retrospring/retrospring" ARG RETROSPRING_VERSION=2023.0131.1 ARG RUBY_VERSION=3.2.2 -ARG RUBY_INSTALL_VERSION=0.9.0 +ARG RUBY_INSTALL_VERSION=0.9.2 ARG BUNDLER_VERSION=2.3.18 ENV RAILS_ENV=production From 2a6d88abfcf7f99d2d52130e243aa04152726205 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Wed, 18 Oct 2023 19:29:44 +0200 Subject: [PATCH 088/590] Include type in relationship unique constraint --- ...8_include_type_in_relationship_unique_constraint.rb | 10 ++++++++++ db/schema.rb | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20231018172518_include_type_in_relationship_unique_constraint.rb diff --git a/db/migrate/20231018172518_include_type_in_relationship_unique_constraint.rb b/db/migrate/20231018172518_include_type_in_relationship_unique_constraint.rb new file mode 100644 index 00000000..171fe00f --- /dev/null +++ b/db/migrate/20231018172518_include_type_in_relationship_unique_constraint.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class IncludeTypeInRelationshipUniqueConstraint < ActiveRecord::Migration[6.1] + def change + change_table :relationships do |t| + t.remove_index(%i[source_id target_id]) + t.index(%i[source_id target_id type], unique: true) + end + end +end diff --git a/db/schema.rb b/db/schema.rb index c45fb69c..ea268655 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_05_26_181715) do +ActiveRecord::Schema.define(version: 2023_10_18_172518) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -159,7 +159,7 @@ ActiveRecord::Schema.define(version: 2023_05_26_181715) do t.datetime "created_at" t.datetime "updated_at" t.string "type", null: false - t.index ["source_id", "target_id"], name: "index_relationships_on_source_id_and_target_id", unique: true + t.index ["source_id", "target_id", "type"], name: "index_relationships_on_source_id_and_target_id_and_type", unique: true t.index ["source_id"], name: "index_relationships_on_source_id" t.index ["target_id"], name: "index_relationships_on_target_id" t.index ["type"], name: "index_relationships_on_type" From dc8c5fbf824b73e5bf149579ef0e7c2fb7442abc Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Wed, 18 Oct 2023 20:01:07 +0200 Subject: [PATCH 089/590] Add option to omit URL to `prepare_tweet` helper --- app/helpers/social_helper/twitter_methods.rb | 4 ++-- spec/helpers/social_helper/twitter_methods_spec.rb | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/helpers/social_helper/twitter_methods.rb b/app/helpers/social_helper/twitter_methods.rb index 7f025f71..716060f8 100644 --- a/app/helpers/social_helper/twitter_methods.rb +++ b/app/helpers/social_helper/twitter_methods.rb @@ -3,7 +3,7 @@ require 'cgi' module SocialHelper::TwitterMethods include MarkdownHelper - def prepare_tweet(answer, post_tag = nil) + def prepare_tweet(answer, post_tag = nil, omit_url = false) question_content = twitter_markdown answer.question.content.gsub(/\@(\w+)/, '\1') original_question_length = question_content.length answer_content = twitter_markdown answer.content @@ -13,7 +13,7 @@ module SocialHelper::TwitterMethods username: answer.user.screen_name, host: APP_CONFIG['hostname'], protocol: (APP_CONFIG['https'] ? :https : :http) - ) + ) unless omit_url parsed_tweet = { :valid => false } tweet_text = "" diff --git a/spec/helpers/social_helper/twitter_methods_spec.rb b/spec/helpers/social_helper/twitter_methods_spec.rb index 7074f6e6..ad630bc4 100644 --- a/spec/helpers/social_helper/twitter_methods_spec.rb +++ b/spec/helpers/social_helper/twitter_methods_spec.rb @@ -38,6 +38,17 @@ describe SocialHelper::TwitterMethods, :type => :helper do end end + context "when the url should be omitted" do + let(:question_content) { "question" } + let(:answer_content) { "answer" } + + subject { prepare_tweet(answer, nil, true) } + + it "should include the suffix after the link" do + expect(subject).to eq("question — answer") + end + end + context 'when a suffix has been passed and the tweet needs to be shortened' do subject { prepare_tweet(answer, '#askracc') } @@ -69,4 +80,4 @@ describe SocialHelper::TwitterMethods, :type => :helper do expect(subject).to eq("https://twitter.com/intent/tweet?text=#{CGI.escape(prepare_tweet(answer))}") end end -end \ No newline at end of file +end From 8b86e2f1233aab000bcde620daaae585feec9406 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Wed, 18 Oct 2023 20:01:59 +0200 Subject: [PATCH 090/590] Set text and URL separately for `navigator.share` Apparently for most mobile OSses `url` is a required share option --- app/controllers/ajax/answer_controller.rb | 6 +++--- app/javascript/retrospring/features/inbox/entry/answer.ts | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/controllers/ajax/answer_controller.rb b/app/controllers/ajax/answer_controller.rb index 0c401638..65f8f29d 100644 --- a/app/controllers/ajax/answer_controller.rb +++ b/app/controllers/ajax/answer_controller.rb @@ -3,9 +3,7 @@ require "cgi" class Ajax::AnswerController < AjaxController - include SocialHelper::TwitterMethods - include SocialHelper::TumblrMethods - include SocialHelper::TelegramMethods + include SocialHelper def create params.require :id @@ -73,6 +71,8 @@ class Ajax::AnswerController < AjaxController private def sharing_hash(answer) = { + url: answer_share_url(answer), + text: prepare_tweet(answer, nil, true), twitter: twitter_share_url(answer), tumblr: tumblr_share_url(answer), telegram: telegram_share_url(answer), diff --git a/app/javascript/retrospring/features/inbox/entry/answer.ts b/app/javascript/retrospring/features/inbox/entry/answer.ts index c515dc30..b5a142ab 100644 --- a/app/javascript/retrospring/features/inbox/entry/answer.ts +++ b/app/javascript/retrospring/features/inbox/entry/answer.ts @@ -32,7 +32,8 @@ export function answerEntryHandler(event: Event): void { const shareButton = inboxEntry.querySelector('[data-controller="share"]'); if (shareButton != null) { - shareButton.dataset.shareTextValue = decodeURIComponent(data.sharing.custom).replaceAll('+', ' '); + shareButton.dataset.shareUrlValue = data.sharing.url; + shareButton.dataset.shareTextValue = data.sharing.text; } const sharing = inboxEntry.querySelector('.inbox-entry__sharing'); From bc45bda5178cb802d6468c74427d2b9ed99bbbbd Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Wed, 18 Oct 2023 20:04:14 +0200 Subject: [PATCH 091/590] Only remove inbox entry after share has been triggered --- .../retrospring/controllers/inbox_sharing_controller.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/javascript/retrospring/controllers/inbox_sharing_controller.ts b/app/javascript/retrospring/controllers/inbox_sharing_controller.ts index d087d62d..dcc7b44f 100644 --- a/app/javascript/retrospring/controllers/inbox_sharing_controller.ts +++ b/app/javascript/retrospring/controllers/inbox_sharing_controller.ts @@ -23,7 +23,7 @@ export default class extends Controller { this.twitterTarget.addEventListener('click', () => this.close()); this.tumblrTarget.addEventListener('click', () => this.close()); this.telegramTarget.addEventListener('click', () => this.close()); - this.otherTarget.addEventListener('click', () => this.close()); + this.otherTarget.addEventListener('click', () => this.closeAfterShare()); if (this.hasCustomTarget) { this.customTarget.addEventListener('click', () => this.close()); @@ -50,4 +50,8 @@ export default class extends Controller { close(): void { (this.element.closest(".inbox-entry")).remove(); } + + closeAfterShare(): void { + this.otherTarget.addEventListener('retrospring:shared', () => this.close()); + } } From 7156dc5c9b629faab8bc123aabdea262a85680b7 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Wed, 18 Oct 2023 20:04:41 +0200 Subject: [PATCH 092/590] Catch `navigator.share` errors with a no-op --- .../retrospring/controllers/share_controller.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/javascript/retrospring/controllers/share_controller.ts b/app/javascript/retrospring/controllers/share_controller.ts index e9e8d250..c1b5d350 100644 --- a/app/javascript/retrospring/controllers/share_controller.ts +++ b/app/javascript/retrospring/controllers/share_controller.ts @@ -1,4 +1,5 @@ import { Controller } from '@hotwired/stimulus'; +import noop from 'utilities/noop'; export default class extends Controller { static values = { @@ -35,8 +36,10 @@ export default class extends Controller { }; } - navigator.share(shareConfiguration).then(() => { - this.element.dispatchEvent(new CustomEvent('retrospring:shared')); - }); + navigator.share(shareConfiguration) + .then(() => { + this.element.dispatchEvent(new CustomEvent('retrospring:shared')); + }) + .catch(noop); } } From 274d480ba82aeae8c03ab053c4e03ca7c50f1595 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Wed, 18 Oct 2023 20:54:41 +0200 Subject: [PATCH 093/590] Adjust specs for AJAX answer endpoint --- spec/controllers/ajax/answer_controller_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/controllers/ajax/answer_controller_spec.rb b/spec/controllers/ajax/answer_controller_spec.rb index 2a8906ca..fd6b50ca 100644 --- a/spec/controllers/ajax/answer_controller_spec.rb +++ b/spec/controllers/ajax/answer_controller_spec.rb @@ -91,6 +91,8 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do let(:expected_response) do super().merge( "sharing" => { + "url" => a_string_matching("https://#{APP_CONFIG['hostname']}/"), + "text" => a_string_matching("Werfen Sie nicht länger das Fenster zum Geld hinaus!"), "twitter" => a_string_matching("https://twitter.com/"), "tumblr" => a_string_matching("https://www.tumblr.com/"), "telegram" => a_string_matching("https://t.me/"), @@ -170,6 +172,8 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do let(:expected_response) do super().merge( "sharing" => { + "url" => a_string_matching("https://#{APP_CONFIG['hostname']}/"), + "text" => a_string_matching("Werfen Sie nicht länger das Fenster zum Geld hinaus!"), "twitter" => a_string_matching("https://twitter.com/"), "tumblr" => a_string_matching("https://www.tumblr.com/"), "telegram" => a_string_matching("https://t.me/"), From f76c4e236b5a7f4350a0a464c9f95f9fdca84f8b Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Wed, 18 Oct 2023 21:07:17 +0200 Subject: [PATCH 094/590] Fix rubocop nits --- app/helpers/social_helper/twitter_methods.rb | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/helpers/social_helper/twitter_methods.rb b/app/helpers/social_helper/twitter_methods.rb index 716060f8..318dd1f9 100644 --- a/app/helpers/social_helper/twitter_methods.rb +++ b/app/helpers/social_helper/twitter_methods.rb @@ -8,12 +8,15 @@ module SocialHelper::TwitterMethods original_question_length = question_content.length answer_content = twitter_markdown answer.content original_answer_length = answer_content.length - answer_url = answer_url( - id: answer.id, - username: answer.user.screen_name, - host: APP_CONFIG['hostname'], - protocol: (APP_CONFIG['https'] ? :https : :http) - ) unless omit_url + + unless omit_url + answer_url = answer_url( + id: answer.id, + username: answer.user.screen_name, + host: APP_CONFIG["hostname"], + protocol: (APP_CONFIG["https"] ? :https : :http), + ) + end parsed_tweet = { :valid => false } tweet_text = "" From dc41f150971f11e5ce45f5775541806b84ca342f Mon Sep 17 00:00:00 2001 From: Georg Gadinger Date: Wed, 18 Oct 2023 21:42:19 +0200 Subject: [PATCH 095/590] fix deletion of inbox entries when deleting an user --- app/models/inbox.rb | 3 ++- spec/models/inbox_spec.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 spec/models/inbox_spec.rb diff --git a/app/models/inbox.rb b/app/models/inbox.rb index 1a1a0066..b12beb29 100644 --- a/app/models/inbox.rb +++ b/app/models/inbox.rb @@ -22,7 +22,8 @@ class Inbox < ApplicationRecord end after_destroy do - user.touch(:inbox_updated_at) + # user might not exist at this point (account deleted, records are cleaned up async) + user&.touch(:inbox_updated_at) end def answer(answer_content, user) diff --git a/spec/models/inbox_spec.rb b/spec/models/inbox_spec.rb new file mode 100644 index 00000000..9a00635a --- /dev/null +++ b/spec/models/inbox_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe Inbox, type: :model do + describe "associations" do + it { should belong_to(:user) } + it { should belong_to(:question) } + end + + describe "before_destroy" do + let(:user) { FactoryBot.create(:user) } + let(:question) { FactoryBot.create(:question, author_is_anonymous: true) } + + it "does not fail if the user wants to delete their account" do + Inbox.create(user:, question:) + + # this deletes the User record and enqueues the deletion of all + # associated records in sidekiq + user.destroy! + + # so let's drain the queues + expect { Sidekiq::Worker.drain_all }.not_to raise_error + end + end +end From 8a26232fe6ce1290aacf99eae11686090d60450f Mon Sep 17 00:00:00 2001 From: Georg Gadinger Date: Wed, 18 Oct 2023 21:53:30 +0200 Subject: [PATCH 096/590] bad dog --- app/models/inbox.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/inbox.rb b/app/models/inbox.rb index b12beb29..ada94803 100644 --- a/app/models/inbox.rb +++ b/app/models/inbox.rb @@ -50,7 +50,7 @@ class Inbox < ApplicationRecord user.profile.anon_display_name || APP_CONFIG["anonymous_name"] else question.user.profile.safe_name - end + end, ), icon: notification_icon, body: question.content.truncate(Question::SHORT_QUESTION_MAX_LENGTH), From b53462e4e5847c351f5e3d7ae22c9d09fc50d4a8 Mon Sep 17 00:00:00 2001 From: Georg Gadinger Date: Wed, 18 Oct 2023 21:55:22 +0200 Subject: [PATCH 097/590] update Bundler --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8f56f560..d9e04dd7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -582,4 +582,4 @@ DEPENDENCIES twitter-text BUNDLED WITH - 2.3.18 + 2.4.21 From f5a77bc882a25790e95287988cd17a7e3b3bf6ba Mon Sep 17 00:00:00 2001 From: Georg Gadinger Date: Wed, 18 Oct 2023 21:55:38 +0200 Subject: [PATCH 098/590] update tldv-data --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d9e04dd7..c9dfd28f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -470,7 +470,7 @@ GEM timeout (0.4.0) tldv (0.1.0) tldv-data (~> 1.0) - tldv-data (1.0.2023031000) + tldv-data (1.0.2023080900) turbo-rails (1.5.0) actionpack (>= 6.0.0) activejob (>= 6.0.0) From a85ce45b25ac921a440d7a94f068a16c73fd070e Mon Sep 17 00:00:00 2001 From: Georg Gadinger Date: Wed, 18 Oct 2023 21:57:09 +0200 Subject: [PATCH 099/590] appease the paw patrol --- app/models/inbox.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/inbox.rb b/app/models/inbox.rb index ada94803..96f3dc84 100644 --- a/app/models/inbox.rb +++ b/app/models/inbox.rb @@ -14,16 +14,16 @@ class Inbox < ApplicationRecord end after_create do - user.touch(:inbox_updated_at) + user.touch(:inbox_updated_at) # rubocop:disable Rails/SkipsModelValidations end after_update do - user.touch(:inbox_updated_at) + user.touch(:inbox_updated_at) # rubocop:disable Rails/SkipsModelValidations end after_destroy do # user might not exist at this point (account deleted, records are cleaned up async) - user&.touch(:inbox_updated_at) + user&.touch(:inbox_updated_at) # rubocop:disable Rails/SkipsModelValidations end def answer(answer_content, user) From c4da510fe71fb0d0d88b88ca730ebeee9d98276c Mon Sep 17 00:00:00 2001 From: Georg Gadinger Date: Wed, 18 Oct 2023 22:13:25 +0200 Subject: [PATCH 100/590] fix deletion of notification entries when deleting a user --- app/models/notification.rb | 7 ++++--- spec/models/notification_spec.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 spec/models/notification_spec.rb diff --git a/app/models/notification.rb b/app/models/notification.rb index e36cad0a..76233c67 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -5,15 +5,16 @@ class Notification < ApplicationRecord belongs_to :target, polymorphic: true after_create do - recipient.touch(:notifications_updated_at) + recipient.touch(:notifications_updated_at) # rubocop:disable Rails/SkipsModelValidations end after_update do - recipient.touch(:notifications_updated_at) + recipient.touch(:notifications_updated_at) # rubocop:disable Rails/SkipsModelValidations end after_destroy do - recipient.touch(:notifications_updated_at) + # recipient might not exist at this point (account deleted, records are cleaned up async) + recipient&.touch(:notifications_updated_at) # rubocop:disable Rails/SkipsModelValidations end class << self diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb new file mode 100644 index 00000000..9bf3aea8 --- /dev/null +++ b/spec/models/notification_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe Notification, type: :model do + describe "associations" do + it { should belong_to(:recipient) } + it { should belong_to(:target) } + end + + describe "before_destroy" do + let(:user) { FactoryBot.create(:user) } + let(:answer) { FactoryBot.create(:answer, user: FactoryBot.create(:user)) } + + it "does not fail if the user wants to delete their account" do + Notification::QuestionAnswered.create(recipient: user, target: answer) + + # this deletes the User record and enqueues the deletion of all + # associated records in sidekiq + user.destroy! + + # so let's drain the queues + expect { Sidekiq::Worker.drain_all }.not_to raise_error + end + end +end From e37532e0ebba5fd64f84727ae4a6e05b9cc2a1dc Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Thu, 19 Oct 2023 10:50:00 +0200 Subject: [PATCH 101/590] Bump version to 2023.1019.0 --- lib/retrospring/version.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/retrospring/version.rb b/lib/retrospring/version.rb index 9046c9d6..5b2806e4 100644 --- a/lib/retrospring/version.rb +++ b/lib/retrospring/version.rb @@ -17,9 +17,9 @@ module Retrospring def month = 10 - def day = 17 + def day = 19 - def patch = 1 + def patch = 0 def suffix = "" From 9cb6b25cc72c8bf48e67dd3215d641994de981b2 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Wed, 18 Oct 2023 23:25:16 +0200 Subject: [PATCH 102/590] Disable `Metrics/*Complexity` cops --- .rubocop.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index 12052185..0d6c9020 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -46,7 +46,10 @@ Metrics/ClassLength: Enabled: false Metrics/CyclomaticComplexity: - Severity: refactor + Enabled: false + +Metrics/PerceivedComplexity: + Enabled: false Metrics/ModuleLength: Enabled: false From 25adb11df3701a119f56d79c0759bd1ef6cd3131 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Wed, 18 Oct 2023 23:26:10 +0200 Subject: [PATCH 103/590] Fix rubocop nits in helper code and specs --- app/helpers/ajax_helper.rb | 2 + .../application_helper/graph_methods.rb | 10 +-- .../application_helper/title_methods.rb | 2 +- app/helpers/bootstrap_helper.rb | 21 +++--- app/helpers/feedback_helper.rb | 2 +- app/helpers/markdown_helper.rb | 2 +- app/helpers/social_helper/telegram_methods.rb | 2 +- app/helpers/social_helper/tumblr_methods.rb | 18 ++--- app/helpers/social_helper/twitter_methods.rb | 20 +++--- app/helpers/theme_helper.rb | 2 +- .../application_helper/graph_methods_spec.rb | 70 +++++++++++-------- .../application_helper/title_methods_spec.rb | 10 +-- spec/helpers/bootstrap_helper_spec.rb | 70 ++++++++++--------- spec/helpers/feedback_helper_spec.rb | 6 +- spec/helpers/markdown_helper_spec.rb | 4 +- .../social_helper/telegram_methods_spec.rb | 4 +- .../social_helper/tumblr_methods_spec.rb | 44 ++++++------ .../social_helper/twitter_methods_spec.rb | 60 ++++++++-------- spec/helpers/social_helper_spec.rb | 3 +- spec/helpers/theme_helper_spec.rb | 36 +++++----- spec/helpers/user_helper_spec.rb | 14 ++-- 21 files changed, 214 insertions(+), 188 deletions(-) diff --git a/app/helpers/ajax_helper.rb b/app/helpers/ajax_helper.rb index 3f1a4867..6a7aa743 100644 --- a/app/helpers/ajax_helper.rb +++ b/app/helpers/ajax_helper.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + module AjaxHelper end diff --git a/app/helpers/application_helper/graph_methods.rb b/app/helpers/application_helper/graph_methods.rb index cde48656..a9487db9 100644 --- a/app/helpers/application_helper/graph_methods.rb +++ b/app/helpers/application_helper/graph_methods.rb @@ -4,13 +4,13 @@ module ApplicationHelper::GraphMethods # Creates tags for OpenGraph properties from a hash # @param values [Hash] def opengraph_meta_tags(values) - safe_join(values.map { |name, content| tag.meta(property: name, content: content) }, "\n") + safe_join(values.map { |name, content| tag.meta(property: name, content:) }, "\n") end # Creates tags from a hash # @param values [Hash] def meta_tags(values) - safe_join(values.map { |name, content| tag.meta(name: name, content: content) }, "\n") + safe_join(values.map { |name, content| tag.meta(name:, content:) }, "\n") end # @param user [User] @@ -22,7 +22,7 @@ module ApplicationHelper::GraphMethods "og:url": user_url(user), "og:description": user.profile.description, "og:site_name": APP_CONFIG["site_name"], - "profile:username": user.screen_name + "profile:username": user.screen_name, }) end @@ -33,7 +33,7 @@ module ApplicationHelper::GraphMethods "twitter:site": "@retrospring", "twitter:title": user.profile.motivation_header.presence || "Ask me anything!", "twitter:description": "Ask #{user.profile.safe_name} anything on Retrospring", - "twitter:image": full_profile_picture_url(user) + "twitter:image": full_profile_picture_url(user), }) end @@ -45,7 +45,7 @@ module ApplicationHelper::GraphMethods "og:image": full_profile_picture_url(answer.user), "og:url": answer_url(answer.user.screen_name, answer.id), "og:description": answer.content, - "og:site_name": APP_CONFIG["site_name"] + "og:site_name": APP_CONFIG["site_name"], }) end diff --git a/app/helpers/application_helper/title_methods.rb b/app/helpers/application_helper/title_methods.rb index b80deee3..9784e646 100644 --- a/app/helpers/application_helper/title_methods.rb +++ b/app/helpers/application_helper/title_methods.rb @@ -28,7 +28,7 @@ module ApplicationHelper::TitleMethods def question_title(question) context_user = question.answers&.first&.user if question.direct name = user_screen_name question.user, - context_user: context_user, + context_user:, author_identifier: question.author_is_anonymous ? question.author_identifier : nil, url: false generate_title name, "asked", question.content diff --git a/app/helpers/bootstrap_helper.rb b/app/helpers/bootstrap_helper.rb index 55544265..e6ae6981 100644 --- a/app/helpers/bootstrap_helper.rb +++ b/app/helpers/bootstrap_helper.rb @@ -25,24 +25,24 @@ module BootstrapHelper "#{content_tag(:i, '', class: "fa fa-#{options[:icon]}")} #{body}" end end - if options[:badge].present? || options.dig(:badge_attr, :data)&.has_key?(:controller) + if options[:badge].present? || options.dig(:badge_attr, :data)&.key?(:controller) badge_class = [ "badge", ("badge-#{options[:badge_color]}" unless options[:badge_color].nil?), ("badge-pill" if options[:badge_pill]) ].compact.join(" ") - body += " #{content_tag(:span, options[:badge], class: badge_class, **options[:badge_attr])}".html_safe + body += " #{content_tag(:span, options[:badge], class: badge_class, **options[:badge_attr])}".html_safe # rubocop:disable Rails/OutputSafety end - content_tag(:li, link_to(body.html_safe, path, class: "nav-link", data: { hotkey: options[:hotkey] }), class: classes, id: options[:id]) + content_tag(:li, link_to(body.html_safe, path, class: "nav-link", data: { hotkey: options[:hotkey] }), class: classes, id: options[:id]) # rubocop:disable Rails/OutputSafety end def list_group_item(body, path, options = {}) options = { badge: nil, badge_color: nil, - class: "" + class: "", }.merge(options) classes = [ @@ -54,13 +54,18 @@ module BootstrapHelper unless options[:badge].nil? || (options[:badge]).zero? # TODO: make this prettier? - body << " #{ - content_tag(:span, options[:badge], class: "badge#{ + badge = content_tag(:span, options[:badge], class: "badge#{ " badge-#{options[:badge_color]}" unless options[:badge_color].nil? - }")}" + }",) end - content_tag(:a, body.html_safe, href: path, class: classes) + html = if badge + "#{body} #{badge}" + else + body + end + + content_tag(:a, html.html_safe, href: path, class: classes) # rubocop:disable Rails/OutputSafety end def tooltip(body, tooltip_content, placement = "bottom") diff --git a/app/helpers/feedback_helper.rb b/app/helpers/feedback_helper.rb index ff51d91b..ac47c27a 100644 --- a/app/helpers/feedback_helper.rb +++ b/app/helpers/feedback_helper.rb @@ -8,7 +8,7 @@ module FeedbackHelper avatarURL: current_user.profile_picture.url(:large), name: current_user.screen_name, id: current_user.id, - email: current_user.email + email: current_user.email, } JWT.encode(user_data, APP_CONFIG.dig("canny", "sso")) diff --git a/app/helpers/markdown_helper.rb b/app/helpers/markdown_helper.rb index ef634209..6ae71c17 100644 --- a/app/helpers/markdown_helper.rb +++ b/app/helpers/markdown_helper.rb @@ -30,7 +30,7 @@ module MarkdownHelper def raw_markdown(content) renderer = Redcarpet::Render::HTML.new(**MARKDOWN_RENDERER_OPTS) md = Redcarpet::Markdown.new(renderer, **MARKDOWN_OPTS) - raw md.render content + raw md.render content # rubocop:disable Rails/OutputSafety end def get_markdown(path, relative_to = Rails.root) diff --git a/app/helpers/social_helper/telegram_methods.rb b/app/helpers/social_helper/telegram_methods.rb index ec13f9ea..046d2392 100644 --- a/app/helpers/social_helper/telegram_methods.rb +++ b/app/helpers/social_helper/telegram_methods.rb @@ -15,7 +15,7 @@ module SocialHelper::TelegramMethods id: answer.id, username: answer.user.screen_name, host: APP_CONFIG["hostname"], - protocol: (APP_CONFIG["https"] ? :https : :http) + protocol: (APP_CONFIG["https"] ? :https : :http), ) %(https://t.me/share/url?url=#{CGI.escape(url)}&text=#{CGI.escape(telegram_text(answer))}) diff --git a/app/helpers/social_helper/tumblr_methods.rb b/app/helpers/social_helper/tumblr_methods.rb index 868f31d3..683199b9 100644 --- a/app/helpers/social_helper/tumblr_methods.rb +++ b/app/helpers/social_helper/tumblr_methods.rb @@ -1,4 +1,6 @@ -require 'cgi' +# frozen_string_literal: true + +require "cgi" module SocialHelper::TumblrMethods def tumblr_title(answer) @@ -13,10 +15,10 @@ module SocialHelper::TumblrMethods def tumblr_body(answer) answer_url = answer_url( - id: answer.id, - username: answer.user.screen_name, - host: APP_CONFIG['hostname'], - protocol: (APP_CONFIG['https'] ? :https : :http) + id: answer.id, + username: answer.user.screen_name, + host: APP_CONFIG["hostname"], + protocol: (APP_CONFIG["https"] ? :https : :http), ) "#{answer.content}\n\n[Smile or comment on the answer here](#{answer_url})" @@ -24,10 +26,10 @@ module SocialHelper::TumblrMethods def tumblr_share_url(answer) answer_url = answer_url( - id: answer.id, + id: answer.id, username: answer.user.screen_name, - host: APP_CONFIG['hostname'], - protocol: (APP_CONFIG['https'] ? :https : :http) + host: APP_CONFIG["hostname"], + protocol: (APP_CONFIG["https"] ? :https : :http), ) "https://www.tumblr.com/widgets/share/tool?shareSource=legacy&posttype=text&title=#{CGI.escape(tumblr_title(answer))}&url=#{CGI.escape(answer_url)}&caption=&content=#{CGI.escape(tumblr_body(answer))}" diff --git a/app/helpers/social_helper/twitter_methods.rb b/app/helpers/social_helper/twitter_methods.rb index 7f025f71..fd143392 100644 --- a/app/helpers/social_helper/twitter_methods.rb +++ b/app/helpers/social_helper/twitter_methods.rb @@ -1,21 +1,23 @@ -require 'cgi' +# frozen_string_literal: true + +require "cgi" module SocialHelper::TwitterMethods include MarkdownHelper def prepare_tweet(answer, post_tag = nil) - question_content = twitter_markdown answer.question.content.gsub(/\@(\w+)/, '\1') + question_content = twitter_markdown answer.question.content.gsub(/@(\w+)/, '\1') original_question_length = question_content.length answer_content = twitter_markdown answer.content original_answer_length = answer_content.length answer_url = answer_url( - id: answer.id, + id: answer.id, username: answer.user.screen_name, - host: APP_CONFIG['hostname'], - protocol: (APP_CONFIG['https'] ? :https : :http) + host: APP_CONFIG["hostname"], + protocol: (APP_CONFIG["https"] ? :https : :http), ) - parsed_tweet = { :valid => false } + parsed_tweet = { valid: false } tweet_text = "" until parsed_tweet[:valid] @@ -23,14 +25,14 @@ module SocialHelper::TwitterMethods shortened_answer = "#{answer_content[0..123]}#{'…' if original_answer_length > [124, answer_content.length].min}" components = [ shortened_question, - '—', + "—", shortened_answer, post_tag, answer_url ] - tweet_text = components.compact.join(' ') + tweet_text = components.compact.join(" ") - parsed_tweet = Twitter::TwitterText::Validation::parse_tweet(tweet_text) + parsed_tweet = Twitter::TwitterText::Validation.parse_tweet(tweet_text) question_content = question_content[0..-2] answer_content = answer_content[0..-2] diff --git a/app/helpers/theme_helper.rb b/app/helpers/theme_helper.rb index 4c1a735f..9cd04910 100644 --- a/app/helpers/theme_helper.rb +++ b/app/helpers/theme_helper.rb @@ -25,7 +25,7 @@ module ThemeHelper "input_color" => "input-bg", "input_text" => "input-text", "input_placeholder" => "input-placeholder", - "muted_text" => "muted-text" + "muted_text" => "muted-text", }.freeze def render_theme diff --git a/spec/helpers/application_helper/graph_methods_spec.rb b/spec/helpers/application_helper/graph_methods_spec.rb index 63baa848..1d79b78c 100644 --- a/spec/helpers/application_helper/graph_methods_spec.rb +++ b/spec/helpers/application_helper/graph_methods_spec.rb @@ -1,20 +1,22 @@ # frozen_string_literal: true -require 'rails_helper' +require "rails_helper" -describe ApplicationHelper::GraphMethods, :type => :helper do +describe ApplicationHelper::GraphMethods, type: :helper do describe "#user_opengraph" do context "sample user" do - let(:user) { FactoryBot.create(:user, - profile: { display_name: 'Cunes', - description: 'A bunch of raccoons in a trenchcoat.' }, - screen_name: 'raccoons') } + let(:user) do + FactoryBot.create(:user, + profile: { display_name: "Cunes", + description: "A bunch of raccoons in a trenchcoat.", }, + screen_name: "raccoons",) + end subject { user_opengraph(user) } - it 'should generate a matching OpenGraph structure for a user' do - allow(APP_CONFIG).to receive(:[]).with('site_name').and_return('pineapplespring') - expect(subject).to eq(<<~EOS.chomp) + it "should generate a matching OpenGraph structure for a user" do + allow(APP_CONFIG).to receive(:[]).with("site_name").and_return("pineapplespring") + expect(subject).to eq(<<~META.chomp) @@ -22,55 +24,63 @@ describe ApplicationHelper::GraphMethods, :type => :helper do - EOS + META end end end describe "#user_twitter_card" do context "sample user" do - let(:user) { FactoryBot.create(:user, - profile: { - display_name: '', - description: 'A bunch of raccoons in a trenchcoat.'}, - screen_name: 'raccoons') } + let(:user) do + FactoryBot.create(:user, + profile: { + display_name: "", + description: "A bunch of raccoons in a trenchcoat.", + }, + screen_name: "raccoons",) + end subject { user_twitter_card(user) } - it 'should generate a matching OpenGraph structure for a user' do - expect(subject).to eq(<<~EOS.chomp) + it "should generate a matching OpenGraph structure for a user" do + expect(subject).to eq(<<~META.chomp) - EOS + META end end end describe "#answer_opengraph" do context "sample user and answer" do - let!(:user) { FactoryBot.create(:user, - profile: { - display_name: '', - description: 'A bunch of raccoons in a trenchcoat.'}, - screen_name: 'raccoons') } - let(:answer) { FactoryBot.create(:answer, - user_id: user.id,) } + let!(:user) do + FactoryBot.create(:user, + profile: { + display_name: "", + description: "A bunch of raccoons in a trenchcoat.", + }, + screen_name: "raccoons",) + end + let(:answer) do + FactoryBot.create(:answer, + user_id: user.id,) + end subject { answer_opengraph(answer) } - it 'should generate a matching OpenGraph structure for a user' do - allow(APP_CONFIG).to receive(:[]).with('site_name').and_return('pineapplespring') - expect(subject).to eq(<<~EOS.chomp) + it "should generate a matching OpenGraph structure for a user" do + allow(APP_CONFIG).to receive(:[]).with("site_name").and_return("pineapplespring") + expect(subject).to eq(<<~META.chomp) - EOS + META end end end -end \ No newline at end of file +end diff --git a/spec/helpers/application_helper/title_methods_spec.rb b/spec/helpers/application_helper/title_methods_spec.rb index 2b3c8bf0..92dc74a8 100644 --- a/spec/helpers/application_helper/title_methods_spec.rb +++ b/spec/helpers/application_helper/title_methods_spec.rb @@ -12,8 +12,8 @@ describe ApplicationHelper::TitleMethods, type: :helper do "anonymous_name" => "Anonymous", "https" => true, "items_per_page" => 5, - "sharing" => {} - }) + "sharing" => {}, + },) user.profile.display_name = "Cool Man" user.profile.save! @@ -42,7 +42,7 @@ describe ApplicationHelper::TitleMethods, type: :helper do context "user has custom anonymous display name" do before do - FactoryBot.create(:answer, question: question, user: user) + FactoryBot.create(:answer, question:, user:) user.profile.anon_display_name = "Amogus" user.profile.save! end @@ -55,9 +55,9 @@ describe ApplicationHelper::TitleMethods, type: :helper do describe "#answer_title" do let(:answer) do - FactoryBot.create(:answer, user: user, + FactoryBot.create(:answer, user:, content: "a", - question_content: "q") + question_content: "q",) end it "should generate a proper title" do diff --git a/spec/helpers/bootstrap_helper_spec.rb b/spec/helpers/bootstrap_helper_spec.rb index 0f31f85e..2f335560 100644 --- a/spec/helpers/bootstrap_helper_spec.rb +++ b/spec/helpers/bootstrap_helper_spec.rb @@ -1,45 +1,47 @@ +# frozen_string_literal: true + require "rails_helper" -describe BootstrapHelper, :type => :helper do +describe BootstrapHelper, type: :helper do include ActiveSupport::Testing::TimeHelpers - describe '#nav_entry' do - it 'should return a HTML navigation item which links to a given address' do + describe "#nav_entry" do + it "should return a HTML navigation item which links to a given address" do allow(self).to receive(:current_page?).and_return(false) - expect(nav_entry('Example', '/example')).to( - eq('') + expect(nav_entry("Example", "/example")).to( + eq(''), ) end - it 'should return with an active attribute if the link matches the current URL' do + it "should return with an active attribute if the link matches the current URL" do allow(self).to receive(:current_page?).and_return(true) - expect(nav_entry('Example', '/example')).to( - eq('') + expect(nav_entry("Example", "/example")).to( + eq(''), ) end - it 'should include an icon if given' do + it "should include an icon if given" do allow(self).to receive(:current_page?).and_return(false) - expect(nav_entry('Example', '/example', icon: 'beaker')).to( - eq('') + expect(nav_entry("Example", "/example", icon: "beaker")).to( + eq(''), ) end - it 'should only include an icon if wanted' do + it "should only include an icon if wanted" do allow(self).to receive(:current_page?).and_return(false) - expect(nav_entry('Example', '/example', icon: 'beaker', icon_only: true)).to( - eq('') + expect(nav_entry("Example", "/example", icon: "beaker", icon_only: true)).to( + eq(''), ) end - it 'should include a badge if given' do + it "should include a badge if given" do allow(self).to receive(:current_page?).and_return(false) - expect(nav_entry('Example', '/example', badge: 3)).to( - eq('') + expect(nav_entry("Example", "/example", badge: 3)).to( + eq(''), ) - expect(nav_entry('Example', '/example', badge: 3, badge_color: 'primary', badge_pill: true)).to( - eq('') + expect(nav_entry("Example", "/example", badge: 3, badge_color: "primary", badge_pill: true)).to( + eq(''), ) end @@ -52,51 +54,51 @@ describe BootstrapHelper, :type => :helper do end describe "#list_group_item" do - it 'should return a HTML navigation item which links to a given address' do + it "should return a HTML navigation item which links to a given address" do allow(self).to receive(:current_page?).and_return(false) - expect(list_group_item('Example', '/example')).to( - eq('Example') + expect(list_group_item("Example", "/example")).to( + eq('Example'), ) end - it 'should return with an active attribute if the link matches the current URL' do + it "should return with an active attribute if the link matches the current URL" do allow(self).to receive(:current_page?).and_return(true) - expect(list_group_item('Example', '/example')).to( - eq('Example') + expect(list_group_item("Example", "/example")).to( + eq('Example'), ) end - it 'should include a badge if given' do + it "should include a badge if given" do allow(self).to receive(:current_page?).and_return(false) - expect(list_group_item('Example', '/example', badge: 3)).to( - eq('Example 3') + expect(list_group_item("Example", "/example", badge: 3)).to( + eq('Example 3'), ) end end describe "#bootstrap_color" do - it 'should map error and alert to danger' do + it "should map error and alert to danger" do expect(bootstrap_color("error")).to eq("danger") expect(bootstrap_color("alert")).to eq("danger") end - it 'should map notice to info' do + it "should map notice to info" do expect(bootstrap_color("notice")).to eq("info") end - it 'should return any uncovered value' do + it "should return any uncovered value" do expect(bootstrap_color("success")).to eq("success") end end describe "#tooltip" do - it 'should return the proper markup' do + it "should return the proper markup" do expect(tooltip("Example Text", "This is in a tooltip")).to eq("Example Text") end end describe "#time_tooltip" do - it 'should return a tooltip with proper time values' do + it "should return a tooltip with proper time values" do travel_to(Time.utc(1984)) do @user = FactoryBot.create(:user) travel 10.minutes @@ -107,7 +109,7 @@ describe BootstrapHelper, :type => :helper do end describe "#hidespan" do - it 'should return the proper markup' do + it "should return the proper markup" do expect(hidespan("Hidden Text", "d-none")).to eq("Hidden Text") end end diff --git a/spec/helpers/feedback_helper_spec.rb b/spec/helpers/feedback_helper_spec.rb index 13d2245e..c5aa16df 100644 --- a/spec/helpers/feedback_helper_spec.rb +++ b/spec/helpers/feedback_helper_spec.rb @@ -11,9 +11,9 @@ describe FeedbackHelper, type: :helper do "canny" => { sso: "sso", feature_board: "feature", - bug_board: "bug" - } - }) + bug_board: "bug", + }, + },) end describe "#canny_token" do diff --git a/spec/helpers/markdown_helper_spec.rb b/spec/helpers/markdown_helper_spec.rb index b4c22b76..39270551 100644 --- a/spec/helpers/markdown_helper_spec.rb +++ b/spec/helpers/markdown_helper_spec.rb @@ -10,8 +10,8 @@ describe MarkdownHelper, type: :helper do "items_per_page" => 5, "allowed_hosts" => [ "twitter.com" - ] - }) + ], + },) end describe "#markdown" do diff --git a/spec/helpers/social_helper/telegram_methods_spec.rb b/spec/helpers/social_helper/telegram_methods_spec.rb index 5e180373..3a72cff8 100644 --- a/spec/helpers/social_helper/telegram_methods_spec.rb +++ b/spec/helpers/social_helper/telegram_methods_spec.rb @@ -9,7 +9,7 @@ describe SocialHelper::TelegramMethods, type: :helper do :answer, user:, content: "this is an answer\nwith multiple lines\nand **FORMATTING**", - question_content: "this is a question .... or is it?" + question_content: "this is a question .... or is it?", ) end @@ -18,7 +18,7 @@ describe SocialHelper::TelegramMethods, type: :helper do "hostname" => "example.com", "https" => true, "items_per_page" => 5, - }) + },) end describe "#telegram_text" do diff --git a/spec/helpers/social_helper/tumblr_methods_spec.rb b/spec/helpers/social_helper/tumblr_methods_spec.rb index 512a35e7..29ba43d0 100644 --- a/spec/helpers/social_helper/tumblr_methods_spec.rb +++ b/spec/helpers/social_helper/tumblr_methods_spec.rb @@ -1,33 +1,35 @@ # frozen_string_literal: true -require 'rails_helper' +require "rails_helper" -describe SocialHelper::TumblrMethods, :type => :helper do +describe SocialHelper::TumblrMethods, type: :helper do let(:user) { FactoryBot.create(:user) } - let(:answer) { FactoryBot.create(:answer, user: user, - content: 'aaaa', - question_content: 'q') } + let(:answer) do + FactoryBot.create(:answer, user:, + content: "aaaa", + question_content: "q",) + end before do stub_const("APP_CONFIG", { - 'hostname' => 'example.com', - 'anonymous_name' => 'Anonymous', - 'https' => true, - 'items_per_page' => 5, - 'sharing' => {} - }) + "hostname" => "example.com", + "anonymous_name" => "Anonymous", + "https" => true, + "items_per_page" => 5, + "sharing" => {}, + },) end - describe '#tumblr_title' do - context 'Asker is anonymous' do + describe "#tumblr_title" do + context "Asker is anonymous" do subject { tumblr_title(answer) } - it 'should return a proper title' do - expect(subject).to eq('Anonymous asked: q') + it "should return a proper title" do + expect(subject).to eq("Anonymous asked: q") end end - context 'Asker is known' do + context "Asker is known" do before do @user = FactoryBot.create(:user) answer.question.user = @user @@ -36,24 +38,24 @@ describe SocialHelper::TumblrMethods, :type => :helper do subject { tumblr_title(answer) } - it 'should return a proper title' do + it "should return a proper title" do expect(subject).to eq("#{answer.question.user.profile.display_name} asked: q") end end end - describe '#tumblr_body' do + describe "#tumblr_body" do subject { tumblr_body(answer) } - it 'should return a proper body' do + it "should return a proper body" do expect(subject).to eq("aaaa\n\n[Smile or comment on the answer here](https://example.com/@#{answer.user.screen_name}/a/#{answer.id})") end end - describe '#tumblr_share_url' do + describe "#tumblr_share_url" do subject { tumblr_share_url(answer) } - it 'should return a proper share link' do + it "should return a proper share link" do expect(subject).to eq("https://www.tumblr.com/widgets/share/tool?shareSource=legacy&posttype=text&title=#{CGI.escape(tumblr_title(answer))}&url=#{CGI.escape("https://example.com/@#{answer.user.screen_name}/a/#{answer.id}")}&caption=&content=#{CGI.escape(tumblr_body(answer))}") end end diff --git a/spec/helpers/social_helper/twitter_methods_spec.rb b/spec/helpers/social_helper/twitter_methods_spec.rb index 7074f6e6..cd97fdcc 100644 --- a/spec/helpers/social_helper/twitter_methods_spec.rb +++ b/spec/helpers/social_helper/twitter_methods_spec.rb @@ -1,72 +1,74 @@ # frozen_string_literal: true -require 'rails_helper' +require "rails_helper" -describe SocialHelper::TwitterMethods, :type => :helper do +describe SocialHelper::TwitterMethods, type: :helper do let(:user) { FactoryBot.create(:user) } - let(:question_content) { 'q' * 255 } - let(:answer_content) { 'a' * 255 } - let(:answer) { FactoryBot.create(:answer, user: user, - content: answer_content, - question_content: question_content) } + let(:question_content) { "q" * 255 } + let(:answer_content) { "a" * 255 } + let(:answer) do + FactoryBot.create(:answer, user:, + content: answer_content, + question_content:,) + end before do stub_const("APP_CONFIG", { - 'hostname' => 'example.com', - 'https' => true, - 'items_per_page' => 5 - }) + "hostname" => "example.com", + "https" => true, + "items_per_page" => 5, + },) end - describe '#prepare_tweet' do - context 'when the question and answer need to be shortened' do + describe "#prepare_tweet" do + context "when the question and answer need to be shortened" do subject { prepare_tweet(answer) } - it 'should return a properly formatted tweet' do + it "should return a properly formatted tweet" do expect(subject).to eq("#{'q' * 123}… — #{'a' * 124}… https://example.com/@#{user.screen_name}/a/#{answer.id}") end end - context 'when a suffix has been passed' do - let(:question_content) { 'question' } - let(:answer_content) { 'answer' } + context "when a suffix has been passed" do + let(:question_content) { "question" } + let(:answer_content) { "answer" } - subject { prepare_tweet(answer, '#askracc') } + subject { prepare_tweet(answer, "#askracc") } - it 'should include the suffix after the link' do + it "should include the suffix after the link" do expect(subject).to eq("question — answer #askracc https://example.com/@#{user.screen_name}/a/#{answer.id}") end end - context 'when a suffix has been passed and the tweet needs to be shortened' do - subject { prepare_tweet(answer, '#askracc') } + context "when a suffix has been passed and the tweet needs to be shortened" do + subject { prepare_tweet(answer, "#askracc") } - it 'should shorten the tweet while keeping the suffix intact' do + it "should shorten the tweet while keeping the suffix intact" do expect(subject).to eq("#{'q' * 120}… — #{'a' * 120}… #askracc https://example.com/@#{user.screen_name}/a/#{answer.id}") end end - context 'when the question and answer are short' do + context "when the question and answer are short" do before do - answer.question.content = 'Why are raccoons so good?' + answer.question.content = "Why are raccoons so good?" answer.question.save! - answer.content = 'Because they are good cunes.' + answer.content = "Because they are good cunes." answer.save! end subject { prepare_tweet(answer) } - it 'should return a properly formatted tweet' do + it "should return a properly formatted tweet" do expect(subject).to eq("#{answer.question.content} — #{answer.content} https://example.com/@#{user.screen_name}/a/#{answer.id}") end end end - describe '#twitter_share_url' do + describe "#twitter_share_url" do subject { twitter_share_url(answer) } - it 'should return a proper share link' do + it "should return a proper share link" do expect(subject).to eq("https://twitter.com/intent/tweet?text=#{CGI.escape(prepare_tweet(answer))}") end end -end \ No newline at end of file +end diff --git a/spec/helpers/social_helper_spec.rb b/spec/helpers/social_helper_spec.rb index 1c165eb0..b56d6ab3 100644 --- a/spec/helpers/social_helper_spec.rb +++ b/spec/helpers/social_helper_spec.rb @@ -18,8 +18,7 @@ describe SocialHelper, type: :helper do "hostname" => "example.com", "https" => true, "items_per_page" => 5, - }, - ) + },) end describe "#answer_share_url" do diff --git a/spec/helpers/theme_helper_spec.rb b/spec/helpers/theme_helper_spec.rb index 3a72ed34..f7de9441 100644 --- a/spec/helpers/theme_helper_spec.rb +++ b/spec/helpers/theme_helper_spec.rb @@ -2,7 +2,7 @@ require "rails_helper" -describe ThemeHelper, :type => :helper do +describe ThemeHelper, type: :helper do describe "#render_theme" do context "when target page doesn't have a theme" do it "returns no theme" do @@ -18,7 +18,7 @@ describe ThemeHelper, :type => :helper do end it "returns a theme" do - expect(helper.render_theme).to include('