Fix NoMethodError for tag moderators channel (#11047)

* Fix NoMethodError for tag moderators channel

In development, it is possible to hit a NoMethodError when adding a tag
moderator because the "tag-moderator" slug is hard-coded.

This change helps mitigate that by adding a safe navigation operator. We
can always remove it if we decide to get rid of the hard-coded value.

Secondarily, it adds this channel to the seeds file, since we pretty
much expect it to exist.

* Move nested conditional
This commit is contained in:
Jacob Herrington 2020-10-23 21:02:54 -05:00 committed by GitHub
parent d5dcda6af6
commit 4dde307a43
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 28 deletions

View file

@ -25,13 +25,14 @@ module AssignTagModerator
end
def self.add_to_chat_channels(user, tag)
channels = user.chat_channels
user_channels = user.chat_channels
ChatChannel.find_by(slug: "tag-moderators").add_users(user) unless channels.exists?(slug: "tag-moderators")
ChatChannel.find_by(slug: "tag-moderators")&.add_users(user) unless
user_channels.exists?(slug: "tag-moderators")
if tag.mod_chat_channel_id
ChatChannel.find(tag.mod_chat_channel_id).add_users(user) unless channels.exists?(id: tag.mod_chat_channel_id)
else
if tag.mod_chat_channel_id && !user_channels.exists?(id: tag.mod_chat_channel_id)
ChatChannel.find(tag.mod_chat_channel_id).add_users(user)
elsif tag.mod_chat_channel_id.blank?
channel = ChatChannels::CreateWithUsers.call(
users: ([user] + User.with_role(:mod_relations_admin)).flatten.uniq,
channel_type: "invite_only",

View file

@ -372,6 +372,13 @@ seeder.create_if_none(ChatChannel) do
)
end
# This channel is hard-coded in a few places
ChatChannel.create!(
channel_name: "Tag Moderators",
channel_type: "open",
slug: "tag-moderators",
)
direct_channel = ChatChannels::CreateWithUsers.call(users: User.last(2), channel_type: "direct")
Message.create!(
chat_channel: direct_channel,

View file

@ -6,40 +6,65 @@ RSpec.describe AssignTagModerator, type: :labor do
let(:mod_relator) { create(:user) }
let(:tag_one) { create(:tag) }
let(:tag_two) { create(:tag) }
let!(:channel) do
create(:chat_channel,
slug: "tag-moderators",
channel_name: "Tag Moderators",
channel_type: "invite_only")
end
before do
def add_tag_moderators
mod_relator.add_role(:mod_relations_admin)
user_ids = [user_one.id, user_two.id]
tag_ids = [tag_one.id, tag_two.id]
ChatChannel.create(slug: "tag-moderators", channel_name: "Tag Moderators", channel_type: "invite_only")
described_class.add_tag_moderators(user_ids, tag_ids)
end
it "assigns the correct moderators and tags" do
expect(tag_two.tag_moderator_ids.count).to eq(1)
def destroy_tag_moderator_channel
channel.destroy
end
it "assigns the mod with the tag that lines up in the array" do
expect(user_one.has_role?(:tag_moderator, tag_one)).to be(true)
expect(user_two.has_role?(:tag_moderator, tag_two)).to be(true)
context "when a tag moderator channel exists" do
before do
add_tag_moderators
end
it "assigns the correct moderators and tags" do
expect(tag_two.tag_moderator_ids.count).to eq(1)
end
it "assigns the mod with the tag that lines up in the array" do
expect(user_one.has_role?(:tag_moderator, tag_one)).to be(true)
expect(user_two.has_role?(:tag_moderator, tag_two)).to be(true)
end
it "adds user to tag moderator channel" do
expect(channel.users.count).to eq(2)
end
it "creates channel and adds user to channel when tag doesn't already have channel" do
tag_channel = ChatChannel.find_by(channel_name: "##{tag_one.name} mods")
expect(tag_one.reload.mod_chat_channel_id).to eq(tag_channel.id)
expect(user_one.chat_channels).to include(tag_channel)
expect(mod_relator.chat_channels).to include(tag_channel)
end
it "adds user to channel when tag already has channel" do
user_three = create(:user)
described_class.add_tag_moderators([user_three.id], [tag_one.id])
channel = ChatChannel.find_by(channel_name: "##{tag_one.name} mods")
expect(channel.active_users).to include(user_three)
end
end
it "adds user to tag moderator channel" do
channel = ChatChannel.find_by(slug: "tag-moderators")
expect(channel.users.count).to eq(2)
end
context "when a tag moderator channel doesn't exist" do
before do
destroy_tag_moderator_channel
end
it "creates channel and adds user to channel when tag doesn't already have channel" do
channel = ChatChannel.find_by(channel_name: "##{tag_one.name} mods")
expect(tag_one.reload.mod_chat_channel_id).to eq(channel.id)
expect(user_one.chat_channels).to include(channel)
expect(mod_relator.chat_channels).to include(channel)
end
it "adds user to channel when tag already has channel" do
user_three = create(:user)
described_class.add_tag_moderators([user_three.id], [tag_one.id])
channel = ChatChannel.find_by(channel_name: "##{tag_one.name} mods")
expect(channel.active_users).to include(user_three)
# Regression test for https://github.com/forem/forem/pull/11047
it "doesn't raise a NoMethodError error" do
expect { add_tag_moderators }.not_to raise_error(NoMethodError)
end
end
end