discourse-chat-integration/spec/helpers/helper_spec.rb

428 lines
14 KiB
Ruby

# frozen_string_literal: true
require "rails_helper"
require_relative "../dummy_provider"
RSpec.describe DiscourseChatIntegration::Manager do
include_context "with dummy provider"
let(:chan1) { DiscourseChatIntegration::Channel.create!(provider: "dummy") }
let(:chan2) { DiscourseChatIntegration::Channel.create!(provider: "dummy") }
let(:category) { Fabricate(:category) }
let(:tag1) { Fabricate(:tag) }
let(:tag2) { Fabricate(:tag) }
let(:tag3) { Fabricate(:tag) }
describe ".process_command" do
describe "add new rule" do
# Not testing how filters are merged here, that's done in .smart_create_rule
# We just want to make sure the commands are being interpretted correctly
it "should add a new rule correctly" do
response = DiscourseChatIntegration::Helper.process_command(chan1, ["watch", category.slug])
expect(response).to eq(I18n.t("chat_integration.provider.dummy.create.created"))
rule = DiscourseChatIntegration::Rule.all.first
expect(rule.channel).to eq(chan1)
expect(rule.filter).to eq("watch")
expect(rule.category_id).to eq(category.id)
expect(rule.tags).to eq(nil)
end
it "should work with all four filter types" do
response =
DiscourseChatIntegration::Helper.process_command(chan1, ["thread", category.slug])
rule = DiscourseChatIntegration::Rule.all.first
expect(rule.filter).to eq("thread")
response = DiscourseChatIntegration::Helper.process_command(chan1, ["watch", category.slug])
rule = DiscourseChatIntegration::Rule.all.first
expect(rule.filter).to eq("watch")
response =
DiscourseChatIntegration::Helper.process_command(chan1, ["follow", category.slug])
rule = DiscourseChatIntegration::Rule.all.first
expect(rule.filter).to eq("follow")
response = DiscourseChatIntegration::Helper.process_command(chan1, ["mute", category.slug])
rule = DiscourseChatIntegration::Rule.all.first
expect(rule.filter).to eq("mute")
end
it "errors on incorrect categories" do
response = DiscourseChatIntegration::Helper.process_command(chan1, %w[watch blah])
expect(response).to eq(
I18n.t(
"chat_integration.provider.dummy.not_found.category",
name: "blah",
list: "uncategorized",
),
)
end
context "with tags enabled" do
before { SiteSetting.tagging_enabled = true }
it "should add a new tag rule correctly" do
response =
DiscourseChatIntegration::Helper.process_command(chan1, ["watch", "tag:#{tag1.name}"])
expect(response).to eq(I18n.t("chat_integration.provider.dummy.create.created"))
rule = DiscourseChatIntegration::Rule.all.first
expect(rule.channel).to eq(chan1)
expect(rule.filter).to eq("watch")
expect(rule.category_id).to eq(nil)
expect(rule.tags).to eq([tag1.name])
end
it "should work with a category and multiple tags" do
response =
DiscourseChatIntegration::Helper.process_command(
chan1,
["watch", category.slug, "tag:#{tag1.name}", "tag:#{tag2.name}"],
)
expect(response).to eq(I18n.t("chat_integration.provider.dummy.create.created"))
rule = DiscourseChatIntegration::Rule.all.first
expect(rule.channel).to eq(chan1)
expect(rule.filter).to eq("watch")
expect(rule.category_id).to eq(category.id)
expect(rule.tags).to contain_exactly(tag1.name, tag2.name)
end
it "errors on incorrect tags" do
response =
DiscourseChatIntegration::Helper.process_command(
chan1,
["watch", category.slug, "tag:blah"],
)
expect(response).to eq(
I18n.t("chat_integration.provider.dummy.not_found.tag", name: "blah"),
)
end
end
end
describe "remove rule" do
it "removes the rule" do
rule1 =
DiscourseChatIntegration::Rule.create(
channel: chan1,
filter: "watch",
category_id: category.id,
tags: [tag1.name, tag2.name],
)
expect(DiscourseChatIntegration::Rule.all.size).to eq(1)
response = DiscourseChatIntegration::Helper.process_command(chan1, %w[remove 1])
expect(response).to eq(I18n.t("chat_integration.provider.dummy.delete.success"))
expect(DiscourseChatIntegration::Rule.all.size).to eq(0)
end
it "errors correctly" do
response = DiscourseChatIntegration::Helper.process_command(chan1, %w[remove 1])
expect(response).to eq(I18n.t("chat_integration.provider.dummy.delete.error"))
end
end
describe "help command" do
it "should return the right response" do
response = DiscourseChatIntegration::Helper.process_command(chan1, ["help"])
expect(response).to eq(I18n.t("chat_integration.provider.dummy.help"))
end
end
describe "status command" do
it "should return the right response" do
response = DiscourseChatIntegration::Helper.process_command(chan1, ["status"])
expect(response).to eq(DiscourseChatIntegration::Helper.status_for_channel(chan1))
end
end
describe "unknown command" do
it "should return the right response" do
response = DiscourseChatIntegration::Helper.process_command(chan1, ["somerandomtext"])
expect(response).to eq(I18n.t("chat_integration.provider.dummy.parse_error"))
end
end
end
describe ".status_for_channel" do
context "with no rules" do
it "includes the heading" do
string = DiscourseChatIntegration::Helper.status_for_channel(chan1)
expect(string).to include("dummy.status.header")
end
it "includes the no_rules string" do
string = DiscourseChatIntegration::Helper.status_for_channel(chan1)
expect(string).to include("dummy.status.no_rules")
end
end
context "with some rules" do
let(:group) { Fabricate(:group) }
before do
DiscourseChatIntegration::Rule.create!(
channel: chan1,
filter: "watch",
category_id: category.id,
tags: nil,
)
DiscourseChatIntegration::Rule.create!(
channel: chan1,
filter: "mute",
category_id: nil,
tags: nil,
)
DiscourseChatIntegration::Rule.create!(
channel: chan1,
filter: "follow",
category_id: nil,
tags: [tag1.name],
)
DiscourseChatIntegration::Rule.create!(
channel: chan1,
filter: "watch",
type: "group_message",
group_id: group.id,
)
DiscourseChatIntegration::Rule.create!(
channel: chan2,
filter: "watch",
category_id: 1,
tags: nil,
)
SiteSetting.tagging_enabled = false
end
it "displays the correct rules" do
string = DiscourseChatIntegration::Helper.status_for_channel(chan1)
expect(string.scan("status.rule_string").size).to eq(4)
end
it "only displays tags for rules with tags" do
string = DiscourseChatIntegration::Helper.status_for_channel(chan1)
expect(string.scan("rule_string_tags_suffix").size).to eq(0)
SiteSetting.tagging_enabled = true
string = DiscourseChatIntegration::Helper.status_for_channel(chan1)
expect(string.scan("rule_string_tags_suffix").size).to eq(1)
end
end
end
describe ".delete_by_index" do
let(:category2) { Fabricate(:category) }
let(:category3) { Fabricate(:category) }
it "deletes the correct rule" do
# Three identical rules, with different filters
# Status will be sorted by precedence
# be in this order
rule1 =
DiscourseChatIntegration::Rule.create(
channel: chan1,
filter: "mute",
category_id: category.id,
tags: [tag1.name, tag2.name],
)
rule2 =
DiscourseChatIntegration::Rule.create(
channel: chan1,
filter: "watch",
category_id: category2.id,
tags: [tag1.name, tag2.name],
)
rule3 =
DiscourseChatIntegration::Rule.create(
channel: chan1,
filter: "follow",
category_id: category3.id,
tags: [tag1.name, tag2.name],
)
expect(DiscourseChatIntegration::Rule.all.size).to eq(3)
expect(DiscourseChatIntegration::Helper.delete_by_index(chan1, 2)).to eq(:deleted)
expect(DiscourseChatIntegration::Rule.all.size).to eq(2)
expect(DiscourseChatIntegration::Rule.all.map(&:category_id)).to contain_exactly(
category.id,
category3.id,
)
end
it "fails gracefully for out of range indexes" do
rule1 =
DiscourseChatIntegration::Rule.create(
channel: chan1,
filter: "watch",
category_id: category.id,
tags: [tag1.name, tag2.name],
)
expect(DiscourseChatIntegration::Helper.delete_by_index(chan1, -1)).to eq(false)
expect(DiscourseChatIntegration::Helper.delete_by_index(chan1, 0)).to eq(false)
expect(DiscourseChatIntegration::Helper.delete_by_index(chan1, 2)).to eq(false)
expect(DiscourseChatIntegration::Helper.delete_by_index(chan1, 1)).to eq(:deleted)
end
end
describe ".smart_create_rule" do
it "creates a rule when there are none" do
val =
DiscourseChatIntegration::Helper.smart_create_rule(
channel: chan1,
filter: "watch",
category_id: category.id,
tags: [tag1.name],
)
expect(val).to eq(:created)
record = DiscourseChatIntegration::Rule.all.first
expect(record.channel).to eq(chan1)
expect(record.filter).to eq("watch")
expect(record.category_id).to eq(category.id)
expect(record.tags).to eq([tag1.name])
end
it "updates a rule when it has the same category and tags" do
existing =
DiscourseChatIntegration::Rule.create!(
channel: chan1,
filter: "watch",
category_id: category.id,
tags: [tag2.name, tag1.name],
)
val =
DiscourseChatIntegration::Helper.smart_create_rule(
channel: chan1,
filter: "mute",
category_id: category.id,
tags: [tag1.name, tag2.name],
)
expect(val).to eq(:updated)
expect(DiscourseChatIntegration::Rule.all.size).to eq(1)
expect(DiscourseChatIntegration::Rule.all.first.filter).to eq("mute")
end
it "updates a rule when it has the same category and filter" do
existing =
DiscourseChatIntegration::Rule.create(
channel: chan1,
filter: "watch",
category_id: category.id,
tags: [tag1.name, tag2.name],
)
val =
DiscourseChatIntegration::Helper.smart_create_rule(
channel: chan1,
filter: "watch",
category_id: category.id,
tags: [tag1.name, tag3.name],
)
expect(val).to eq(:updated)
expect(DiscourseChatIntegration::Rule.all.size).to eq(1)
expect(DiscourseChatIntegration::Rule.all.first.tags).to contain_exactly(
tag1.name,
tag2.name,
tag3.name,
)
end
it "destroys duplicate rules on save" do
DiscourseChatIntegration::Rule.create!(channel: chan1, filter: "watch")
DiscourseChatIntegration::Rule.create!(channel: chan1, filter: "watch")
expect(DiscourseChatIntegration::Rule.all.size).to eq(2)
val =
DiscourseChatIntegration::Helper.smart_create_rule(
channel: chan1,
filter: "watch",
category_id: nil,
tags: nil,
)
expect(val).to eq(:updated)
expect(DiscourseChatIntegration::Rule.all.size).to eq(1)
end
it "returns false on error" do
val = DiscourseChatIntegration::Helper.smart_create_rule(channel: chan1, filter: "blah")
expect(val).to eq(false)
end
end
describe ".save_transcript" do
it "saves a transcript to redis" do
key = DiscourseChatIntegration::Helper.save_transcript("Some content here")
expect(Discourse.redis.get("chat_integration:transcript:#{key}")).to eq("Some content here")
ttl = Discourse.redis.pttl("chat_integration:transcript:#{key}")
# Slight hack since freeze_time doens't work on redis
expect(Discourse.redis.pttl("chat_integration:transcript:#{key}")).to be <= (3601 * 1000)
expect(Discourse.redis.pttl("chat_integration:transcript:#{key}")).to be >= (3599 * 1000)
end
end
describe ".formatted_display_name" do
let(:user) { Fabricate(:user, name: "John Smith", username: "js1") }
it "prioritizes correctly" do
SiteSetting.prioritize_username_in_ux = true
expect(DiscourseChatIntegration::Helper.formatted_display_name(user)).to eq(
"@#{user.username} (John Smith)",
)
SiteSetting.prioritize_username_in_ux = false
expect(DiscourseChatIntegration::Helper.formatted_display_name(user)).to eq(
"John Smith (@#{user.username})",
)
end
it "only displays one when name/username are similar" do
user.update!(username: "john_smith")
SiteSetting.prioritize_username_in_ux = true
expect(DiscourseChatIntegration::Helper.formatted_display_name(user)).to eq(
"@#{user.username}",
)
SiteSetting.prioritize_username_in_ux = false
expect(DiscourseChatIntegration::Helper.formatted_display_name(user)).to eq("John Smith")
end
it "only displays username when names are disabled" do
SiteSetting.enable_names = false
SiteSetting.prioritize_username_in_ux = true
expect(DiscourseChatIntegration::Helper.formatted_display_name(user)).to eq(
"@#{user.username}",
)
SiteSetting.prioritize_username_in_ux = false
expect(DiscourseChatIntegration::Helper.formatted_display_name(user)).to eq(
"@#{user.username}",
)
end
end
end