2017-07-05 18:00:58 -04:00
|
|
|
require 'rails_helper'
|
2017-07-13 17:13:03 -04:00
|
|
|
require_relative '../dummy_provider'
|
2017-07-05 18:00:58 -04:00
|
|
|
|
|
|
|
RSpec.describe DiscourseChat::Manager do
|
2017-07-13 17:13:03 -04:00
|
|
|
include_context "dummy provider"
|
|
|
|
|
|
|
|
let(:chan1){DiscourseChat::Channel.create!(provider:'dummy')}
|
|
|
|
let(:chan2){DiscourseChat::Channel.create!(provider:'dummy')}
|
|
|
|
|
|
|
|
let(:category) {Fabricate(:category)}
|
2017-07-05 18:00:58 -04:00
|
|
|
|
|
|
|
let(:category) {Fabricate(:category)}
|
|
|
|
let(:tag1){Fabricate(:tag)}
|
2017-07-05 20:11:26 -04:00
|
|
|
let(:tag2){Fabricate(:tag)}
|
|
|
|
let(:tag3){Fabricate(:tag)}
|
2017-07-05 18:00:58 -04:00
|
|
|
|
2017-07-19 13:22:50 -04:00
|
|
|
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 = DiscourseChat::Helper.process_command(chan1, ['watch',category.slug])
|
|
|
|
|
|
|
|
expect(response).to eq(I18n.t("chat_integration.provider.dummy.create.created"))
|
|
|
|
|
|
|
|
rule = DiscourseChat::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 three filter types' do
|
|
|
|
response = DiscourseChat::Helper.process_command(chan1, ['watch',category.slug])
|
|
|
|
|
|
|
|
rule = DiscourseChat::Rule.all.first
|
|
|
|
expect(rule.filter).to eq('watch')
|
|
|
|
|
|
|
|
response = DiscourseChat::Helper.process_command(chan1, ['follow',category.slug])
|
|
|
|
|
|
|
|
rule = DiscourseChat::Rule.all.first
|
|
|
|
expect(rule.filter).to eq('follow')
|
|
|
|
|
|
|
|
response = DiscourseChat::Helper.process_command(chan1, ['mute',category.slug])
|
|
|
|
|
|
|
|
rule = DiscourseChat::Rule.all.first
|
|
|
|
expect(rule.filter).to eq('mute')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'errors on incorrect categories' do
|
|
|
|
response = DiscourseChat::Helper.process_command(chan1, ['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 do
|
|
|
|
SiteSetting.tagging_enabled = true
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should add a new tag rule correctly' do
|
|
|
|
response = DiscourseChat::Helper.process_command(chan1, ['watch',"tag:#{tag1.name}"])
|
|
|
|
|
|
|
|
expect(response).to eq(I18n.t("chat_integration.provider.dummy.create.created"))
|
|
|
|
|
|
|
|
rule = DiscourseChat::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 = DiscourseChat::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 = DiscourseChat::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 = DiscourseChat::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 = DiscourseChat::Rule.create(channel: chan1,
|
|
|
|
filter: 'watch',
|
|
|
|
category_id: category.id,
|
|
|
|
tags: [tag1.name, tag2.name]
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(DiscourseChat::Rule.all.size).to eq(1)
|
|
|
|
|
|
|
|
response = DiscourseChat::Helper.process_command(chan1, ['remove','1'])
|
|
|
|
|
|
|
|
expect(response).to eq(I18n.t("chat_integration.provider.dummy.delete.success"))
|
|
|
|
|
|
|
|
expect(DiscourseChat::Rule.all.size).to eq(0)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'errors correctly' do
|
|
|
|
response = DiscourseChat::Helper.process_command(chan1, ['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 = DiscourseChat::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 = DiscourseChat::Helper.process_command(chan1, ['status'])
|
|
|
|
expect(response).to eq(DiscourseChat::Helper.status_for_channel(chan1))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'unknown command' do
|
|
|
|
it 'should return the right response' do
|
|
|
|
response = DiscourseChat::Helper.process_command(chan1, ['somerandomtext'])
|
|
|
|
expect(response).to eq(I18n.t("chat_integration.provider.dummy.parse_error"))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-07-05 18:00:58 -04:00
|
|
|
describe '.status_for_channel' do
|
|
|
|
|
|
|
|
context 'with no rules' do
|
|
|
|
it 'includes the heading' do
|
2017-07-13 17:13:03 -04:00
|
|
|
string = DiscourseChat::Helper.status_for_channel(chan1)
|
|
|
|
expect(string).to include('dummy.status.header')
|
2017-07-05 18:00:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'includes the no_rules string' do
|
2017-07-13 17:13:03 -04:00
|
|
|
string = DiscourseChat::Helper.status_for_channel(chan1)
|
|
|
|
expect(string).to include('dummy.status.no_rules')
|
2017-07-05 18:00:58 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with some rules' do
|
2017-08-01 14:16:47 -04:00
|
|
|
let(:group){Fabricate(:group)}
|
2017-07-05 18:00:58 -04:00
|
|
|
before do
|
2017-07-13 17:13:03 -04:00
|
|
|
DiscourseChat::Rule.create!(channel: chan1, filter:'watch', category_id:category.id, tags:nil)
|
|
|
|
DiscourseChat::Rule.create!(channel: chan1, filter:'mute', category_id:nil, tags:nil)
|
|
|
|
DiscourseChat::Rule.create!(channel: chan1, filter:'follow', category_id:nil, tags:[tag1.name])
|
2017-08-01 14:16:47 -04:00
|
|
|
DiscourseChat::Rule.create!(channel: chan1, filter:'watch', type: 'group_message', group_id:group.id)
|
2017-07-13 17:13:03 -04:00
|
|
|
DiscourseChat::Rule.create!(channel: chan2, filter:'watch', category_id:1, tags:nil)
|
2017-07-05 18:00:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'displays the correct rules' do
|
2017-07-13 17:13:03 -04:00
|
|
|
string = DiscourseChat::Helper.status_for_channel(chan1)
|
2017-08-01 14:16:47 -04:00
|
|
|
expect(string.scan('status.rule_string').size).to eq(4)
|
2017-07-05 18:00:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'only displays tags for rules with tags' do
|
2017-07-13 17:13:03 -04:00
|
|
|
string = DiscourseChat::Helper.status_for_channel(chan1)
|
|
|
|
expect(string.scan('rule_string_tags_suffix').size).to eq(0)
|
2017-07-05 18:00:58 -04:00
|
|
|
|
|
|
|
SiteSetting.tagging_enabled = true
|
2017-07-13 17:13:03 -04:00
|
|
|
string = DiscourseChat::Helper.status_for_channel(chan1)
|
|
|
|
expect(string.scan('rule_string_tags_suffix').size).to eq(1)
|
2017-07-05 18:00:58 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-07-06 16:36:50 -04:00
|
|
|
describe '.delete_by_index' do
|
|
|
|
let(:category2) {Fabricate(:category)}
|
|
|
|
let(:category3) {Fabricate(:category)}
|
|
|
|
|
|
|
|
it 'deletes the correct rule' do
|
2017-07-26 16:14:29 -04:00
|
|
|
# Three identical rules, with different filters
|
|
|
|
# Status will be sorted by precedence
|
2017-07-06 16:36:50 -04:00
|
|
|
# be in this order
|
2017-07-13 17:13:03 -04:00
|
|
|
rule1 = DiscourseChat::Rule.create(channel: chan1,
|
2017-07-26 16:14:29 -04:00
|
|
|
filter: 'mute',
|
2017-07-13 17:13:03 -04:00
|
|
|
category_id: category.id,
|
|
|
|
tags: [tag1.name, tag2.name]
|
|
|
|
)
|
|
|
|
rule2 = DiscourseChat::Rule.create(channel: chan1,
|
|
|
|
filter: 'watch',
|
|
|
|
category_id: category2.id,
|
|
|
|
tags: [tag1.name, tag2.name]
|
|
|
|
)
|
|
|
|
rule3 = DiscourseChat::Rule.create(channel: chan1,
|
2017-07-26 16:14:29 -04:00
|
|
|
filter: 'follow',
|
2017-07-13 17:13:03 -04:00
|
|
|
category_id: category3.id,
|
|
|
|
tags: [tag1.name, tag2.name]
|
|
|
|
)
|
2017-07-06 16:36:50 -04:00
|
|
|
|
|
|
|
expect(DiscourseChat::Rule.all.size).to eq(3)
|
|
|
|
|
2017-07-13 17:13:03 -04:00
|
|
|
expect(DiscourseChat::Helper.delete_by_index(chan1,2)).to eq(:deleted)
|
2017-07-06 16:36:50 -04:00
|
|
|
|
|
|
|
expect(DiscourseChat::Rule.all.size).to eq(2)
|
|
|
|
expect(DiscourseChat::Rule.all.map(&:category_id)).to contain_exactly(category.id, category3.id)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'fails gracefully for out of range indexes' do
|
2017-07-13 17:13:03 -04:00
|
|
|
rule1 = DiscourseChat::Rule.create(channel: chan1,
|
|
|
|
filter: 'watch',
|
|
|
|
category_id: category.id,
|
|
|
|
tags: [tag1.name, tag2.name]
|
|
|
|
)
|
2017-07-06 16:36:50 -04:00
|
|
|
|
2017-07-13 17:13:03 -04:00
|
|
|
expect(DiscourseChat::Helper.delete_by_index(chan1,-1)).to eq(false)
|
|
|
|
expect(DiscourseChat::Helper.delete_by_index(chan1,0)).to eq(false)
|
|
|
|
expect(DiscourseChat::Helper.delete_by_index(chan1,2)).to eq(false)
|
2017-07-06 16:36:50 -04:00
|
|
|
|
2017-07-13 17:13:03 -04:00
|
|
|
expect(DiscourseChat::Helper.delete_by_index(chan1,1)).to eq(:deleted)
|
2017-07-06 16:36:50 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-07-05 20:11:26 -04:00
|
|
|
describe '.smart_create_rule' do
|
|
|
|
|
|
|
|
it 'creates a rule when there are none' do
|
2017-07-13 17:13:03 -04:00
|
|
|
val = DiscourseChat::Helper.smart_create_rule(channel: chan1,
|
2017-07-05 20:11:26 -04:00
|
|
|
filter: 'watch',
|
|
|
|
category_id: category.id,
|
|
|
|
tags: [tag1.name]
|
|
|
|
)
|
|
|
|
expect(val).to eq(:created)
|
|
|
|
|
|
|
|
record = DiscourseChat::Rule.all.first
|
2017-07-13 17:13:03 -04:00
|
|
|
expect(record.channel).to eq(chan1)
|
2017-07-05 20:11:26 -04:00
|
|
|
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
|
2017-07-13 17:13:03 -04:00
|
|
|
existing = DiscourseChat::Rule.create!(channel:chan1,
|
2017-07-05 20:11:26 -04:00
|
|
|
filter: 'watch',
|
|
|
|
category_id: category.id,
|
|
|
|
tags: [tag2.name, tag1.name]
|
2017-07-13 17:13:03 -04:00
|
|
|
)
|
2017-07-05 20:11:26 -04:00
|
|
|
|
2017-07-13 17:13:03 -04:00
|
|
|
val = DiscourseChat::Helper.smart_create_rule(channel: chan1,
|
2017-07-05 20:11:26 -04:00
|
|
|
filter: 'mute',
|
|
|
|
category_id: category.id,
|
|
|
|
tags: [tag1.name, tag2.name]
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(val).to eq(:updated)
|
|
|
|
|
|
|
|
expect(DiscourseChat::Rule.all.size).to eq(1)
|
|
|
|
expect(DiscourseChat::Rule.all.first.filter).to eq('mute')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'updates a rule when it has the same category and filter' do
|
2017-07-13 17:13:03 -04:00
|
|
|
existing = DiscourseChat::Rule.create(channel: chan1,
|
|
|
|
filter: 'watch',
|
|
|
|
category_id: category.id,
|
|
|
|
tags: [tag1.name, tag2.name]
|
|
|
|
)
|
2017-07-05 20:11:26 -04:00
|
|
|
|
2017-07-13 17:13:03 -04:00
|
|
|
val = DiscourseChat::Helper.smart_create_rule(channel: chan1,
|
2017-07-05 20:11:26 -04:00
|
|
|
filter: 'watch',
|
|
|
|
category_id: category.id,
|
|
|
|
tags: [tag1.name, tag3.name]
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(val).to eq(:updated)
|
|
|
|
|
|
|
|
expect(DiscourseChat::Rule.all.size).to eq(1)
|
|
|
|
expect(DiscourseChat::Rule.all.first.tags).to contain_exactly(tag1.name, tag2.name, tag3.name)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'destroys duplicate rules on save' do
|
2017-07-13 17:13:03 -04:00
|
|
|
DiscourseChat::Rule.create!(channel: chan1, filter: 'watch')
|
|
|
|
DiscourseChat::Rule.create!(channel: chan1, filter: 'watch')
|
2017-07-05 20:11:26 -04:00
|
|
|
expect(DiscourseChat::Rule.all.size).to eq(2)
|
2017-07-13 17:13:03 -04:00
|
|
|
val = DiscourseChat::Helper.smart_create_rule(channel: chan1,
|
2017-07-05 20:11:26 -04:00
|
|
|
filter: 'watch',
|
|
|
|
category_id: nil,
|
|
|
|
tags: nil
|
|
|
|
)
|
|
|
|
expect(val).to eq(:updated)
|
|
|
|
expect(DiscourseChat::Rule.all.size).to eq(1)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false on error' do
|
2017-07-13 17:13:03 -04:00
|
|
|
val = DiscourseChat::Helper.smart_create_rule(channel: chan1, filter: 'blah')
|
2017-07-05 20:11:26 -04:00
|
|
|
|
|
|
|
expect(val).to eq(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-07-24 11:13:53 -04:00
|
|
|
describe '.save_transcript' do
|
|
|
|
|
|
|
|
it 'saves a transcript to redis' do
|
|
|
|
key = DiscourseChat::Helper.save_transcript("Some content here")
|
|
|
|
|
|
|
|
expect($redis.get("chat_integration:transcript:#{key}")).to eq("Some content here")
|
2017-07-24 12:48:06 -04:00
|
|
|
|
|
|
|
ttl = $redis.pttl("chat_integration:transcript:#{key}")
|
|
|
|
|
|
|
|
# Slight hack since freeze_time doens't work on redis
|
|
|
|
expect($redis.pttl("chat_integration:transcript:#{key}")).to be <= (3601*1000)
|
|
|
|
expect($redis.pttl("chat_integration:transcript:#{key}")).to be >= (3599*1000)
|
2017-07-24 11:13:53 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-07-05 18:00:58 -04:00
|
|
|
end
|