diff --git a/app/models/mute_rule.rb b/app/models/mute_rule.rb new file mode 100644 index 00000000..14cfabf2 --- /dev/null +++ b/app/models/mute_rule.rb @@ -0,0 +1,7 @@ +class MuteRule < ApplicationRecord + belongs_to :user + + def applies_to?(post) + !!(post.content =~ /\b#{muted_phrase}\b/i) + end +end diff --git a/app/workers/question_worker.rb b/app/workers/question_worker.rb index b49ced7c..cd054e6b 100644 --- a/app/workers/question_worker.rb +++ b/app/workers/question_worker.rb @@ -9,9 +9,12 @@ class QuestionWorker # @param question_id [Integer] newly created question id def perform(user_id, question_id) user = User.find(user_id) + question = Question.find(question_id) user.followers.each do |f| - Inbox.create(user_id: f.id, question_id: question_id, new: true) + unless MuteRule.where(user: f).any? { |rule| rule.applies_to? question } + Inbox.create(user_id: f.id, question_id: question_id, new: true) + end end rescue StandardError => e logger.info "failed to ask question: #{e.message}" diff --git a/db/migrate/20211222165159_create_mute_rules.rb b/db/migrate/20211222165159_create_mute_rules.rb new file mode 100644 index 00000000..417aeec8 --- /dev/null +++ b/db/migrate/20211222165159_create_mute_rules.rb @@ -0,0 +1,10 @@ +class CreateMuteRules < ActiveRecord::Migration[5.2] + def change + create_table :mute_rules do |t| + t.references :user, foreign_key: true + t.string :muted_phrase + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 017794d2..7fb74408 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -107,6 +107,14 @@ ActiveRecord::Schema.define(version: 2021_12_28_135426) do t.index ["user_id"], name: "index_moderation_votes_on_user_id" end + create_table "mute_rules", force: :cascade do |t| + t.bigint "user_id" + t.string "muted_phrase" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_mute_rules_on_user_id" + end + create_table "notifications", id: :serial, force: :cascade do |t| t.string "target_type" t.bigint "target_id" @@ -306,4 +314,5 @@ ActiveRecord::Schema.define(version: 2021_12_28_135426) do end add_foreign_key "profiles", "users" + add_foreign_key "mute_rules", "users" end diff --git a/spec/models/mute_rule_spec.rb b/spec/models/mute_rule_spec.rb new file mode 100644 index 00000000..5d47fac6 --- /dev/null +++ b/spec/models/mute_rule_spec.rb @@ -0,0 +1,13 @@ +require 'rails_helper' + +RSpec.describe MuteRule, type: :model do + describe "#applies_to?" do + let(:user) { FactoryBot.create(:user) } + let(:rule) { MuteRule.create(user: user, muted_phrase: "trial") } + let(:question) { Question.create(user: user, content: "Did you know that the critically acclaimed MMORPG Final Fantasy XIV has a free trial, and includes the entirety of A Realm Reborn AND the award-winning Heavensward expansion up to level 60 with no restrictions on playtime?") } + + it "only returns true for questions matching a certain phrase" do + expect(rule.applies_to?(question)).to be(true) + end + end +end diff --git a/spec/workers/question_worker_spec.rb b/spec/workers/question_worker_spec.rb index 832276ac..dc069f82 100644 --- a/spec/workers/question_worker_spec.rb +++ b/spec/workers/question_worker_spec.rb @@ -26,5 +26,19 @@ describe QuestionWorker do .to(5) ) end + + it "respects mute rules" do + question.content = 'Some spicy question text' + question.save + + MuteRule.create(user_id: user.followers.first.id, muted_phrase: 'spicy') + + expect { subject } + .to( + change { Inbox.where(user_id: user.followers.ids, question_id: question_id, new: true).count } + .from(0) + .to(4) + ) + end end end