2017-06-27 14:21:27 -04:00
|
|
|
require 'rails_helper'
|
|
|
|
require_dependency 'post_creator'
|
|
|
|
|
|
|
|
RSpec.describe DiscourseChat::Manager do
|
|
|
|
|
|
|
|
let(:manager) {::DiscourseChat::Manager}
|
|
|
|
let(:category) {Fabricate(:category)}
|
|
|
|
let(:topic){Fabricate(:topic, category_id: category.id )}
|
|
|
|
let(:first_post) {Fabricate(:post, topic: topic)}
|
|
|
|
let(:second_post) {Fabricate(:post, topic: topic, post_number:2)}
|
|
|
|
|
|
|
|
describe '.trigger_notifications' do
|
2017-07-03 10:53:26 -04:00
|
|
|
before do
|
|
|
|
SiteSetting.chat_integration_enabled = true
|
|
|
|
end
|
|
|
|
|
2017-06-27 14:21:27 -04:00
|
|
|
before(:each) do
|
|
|
|
module ::DiscourseChat::Provider::DummyProvider
|
|
|
|
PROVIDER_NAME = "dummy".freeze
|
2017-07-03 10:53:26 -04:00
|
|
|
PROVIDER_ENABLED_SETTING = :chat_integration_enabled # Tie to main plugin enabled setting
|
2017-06-27 14:21:27 -04:00
|
|
|
@@sent_messages = []
|
2017-07-04 14:37:56 -04:00
|
|
|
@@raise_exception = nil
|
2017-06-27 14:21:27 -04:00
|
|
|
|
|
|
|
def self.trigger_notification(post, channel)
|
2017-07-04 14:37:56 -04:00
|
|
|
if @@raise_exception
|
|
|
|
raise @@raise_exception
|
|
|
|
end
|
2017-06-27 14:21:27 -04:00
|
|
|
@@sent_messages.push(post: post.id, channel: channel)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.sent_messages
|
|
|
|
@@sent_messages
|
|
|
|
end
|
2017-07-04 14:37:56 -04:00
|
|
|
|
|
|
|
def self.set_raise_exception(bool)
|
|
|
|
@@raise_exception = bool
|
|
|
|
end
|
2017-06-27 14:21:27 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
after(:each) do
|
|
|
|
::DiscourseChat::Provider.send(:remove_const, :DummyProvider)
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:provider) {::DiscourseChat::Provider::DummyProvider}
|
|
|
|
|
2017-06-29 12:50:54 -04:00
|
|
|
def create_rule(provider, channel, filter, category_id, tags) # Just shorthand for testing purposes
|
2017-07-03 12:38:13 -04:00
|
|
|
DiscourseChat::Rule.new({provider: provider, channel: channel, filter:filter, category_id:category_id, tags:tags}).save!
|
2017-06-29 12:50:54 -04:00
|
|
|
end
|
|
|
|
|
2017-07-04 14:37:56 -04:00
|
|
|
it "should fail gracefully when a provider throws an exception" do
|
|
|
|
create_rule('dummy', 'chan1', 'watch', category.id, nil)
|
|
|
|
|
|
|
|
# Triggering a ProviderError should set the error_key to the error message
|
|
|
|
::DiscourseChat::Provider::DummyProvider.set_raise_exception(DiscourseChat::ProviderError.new info: {error_key:"hello"})
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly()
|
|
|
|
expect(DiscourseChat::Rule.all.first.error_key).to eq('hello')
|
|
|
|
|
|
|
|
# Triggering a different error should set the error_key to a generic message
|
|
|
|
::DiscourseChat::Provider::DummyProvider.set_raise_exception(StandardError.new "hello")
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly()
|
|
|
|
expect(DiscourseChat::Rule.all.first.error_key).to eq('chat_integration.rule_exception')
|
|
|
|
|
|
|
|
::DiscourseChat::Provider::DummyProvider.set_raise_exception(nil)
|
|
|
|
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
expect(DiscourseChat::Rule.all.first.error_key.nil?).to be true
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should not send notifications when provider is disabled" do
|
2017-07-03 10:53:26 -04:00
|
|
|
SiteSetting.chat_integration_enabled = false
|
|
|
|
create_rule('dummy', 'chan1', 'watch', category.id, nil)
|
|
|
|
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly()
|
|
|
|
end
|
|
|
|
|
2017-06-27 14:21:27 -04:00
|
|
|
it "should send a notification to watched and following channels for new topic" do
|
2017-06-29 12:50:54 -04:00
|
|
|
|
|
|
|
create_rule('dummy', 'chan1', 'watch', category.id, nil)
|
|
|
|
create_rule('dummy', 'chan2', 'follow', category.id, nil)
|
|
|
|
create_rule('dummy', 'chan3', 'mute', category.id, nil)
|
2017-06-27 14:21:27 -04:00
|
|
|
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly('chan1', 'chan2')
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should send a notification only to watched for reply" do
|
2017-06-29 12:50:54 -04:00
|
|
|
create_rule('dummy', 'chan1', 'watch', category.id, nil)
|
|
|
|
create_rule('dummy', 'chan2', 'follow', category.id, nil)
|
|
|
|
create_rule('dummy', 'chan3', 'mute', category.id, nil)
|
2017-06-27 14:21:27 -04:00
|
|
|
|
|
|
|
manager.trigger_notifications(second_post.id)
|
|
|
|
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly('chan1')
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should respect wildcard category settings" do
|
2017-06-29 12:50:54 -04:00
|
|
|
create_rule('dummy', 'chan1', 'watch', nil, nil)
|
2017-06-27 14:21:27 -04:00
|
|
|
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly('chan1')
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should respect mute over watch" do
|
2017-06-29 12:50:54 -04:00
|
|
|
create_rule('dummy', 'chan1', 'watch', nil, nil) # Wildcard watch
|
|
|
|
create_rule('dummy', 'chan1', 'mute', category.id, nil) # Specific mute
|
2017-06-27 14:21:27 -04:00
|
|
|
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly()
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should respect watch over follow" do
|
2017-06-29 12:50:54 -04:00
|
|
|
create_rule('dummy', 'chan1', 'follow', nil, nil)
|
|
|
|
create_rule('dummy', 'chan1', 'watch', category.id, nil)
|
2017-06-27 14:21:27 -04:00
|
|
|
|
|
|
|
manager.trigger_notifications(second_post.id)
|
|
|
|
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly('chan1')
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should not notify about private messages" do
|
2017-06-29 12:50:54 -04:00
|
|
|
create_rule('dummy', 'chan1', 'watch', nil, nil)
|
2017-06-27 14:21:27 -04:00
|
|
|
private_post = Fabricate(:private_message_post)
|
|
|
|
|
|
|
|
manager.trigger_notifications(private_post.id)
|
|
|
|
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly()
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should not notify about private messages" do
|
2017-06-29 12:50:54 -04:00
|
|
|
create_rule('dummy', 'chan1', 'watch', nil, nil)
|
2017-06-27 14:21:27 -04:00
|
|
|
private_post = Fabricate(:private_message_post)
|
|
|
|
|
|
|
|
manager.trigger_notifications(private_post.id)
|
|
|
|
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly()
|
|
|
|
end
|
|
|
|
|
|
|
|
it "should not notify about posts the chat_user cannot see" do
|
2017-06-29 12:50:54 -04:00
|
|
|
create_rule('dummy', 'chan1', 'watch', nil, nil)
|
2017-06-27 14:21:27 -04:00
|
|
|
|
|
|
|
# Create a group & user
|
|
|
|
group = Fabricate(:group, name: "friends")
|
|
|
|
user = Fabricate(:user, username: 'david')
|
|
|
|
group.add(user)
|
|
|
|
|
|
|
|
# Set the chat_user to the newly created non-admin user
|
2017-07-03 06:08:14 -04:00
|
|
|
SiteSetting.chat_integration_discourse_username = 'david'
|
2017-06-27 14:21:27 -04:00
|
|
|
|
|
|
|
# Create a category
|
|
|
|
category = Fabricate(:category, name: "Test category")
|
|
|
|
topic.category = category
|
|
|
|
topic.save!
|
|
|
|
|
|
|
|
# Restrict category to admins only
|
|
|
|
category.set_permissions(Group[:admins] => :full)
|
|
|
|
category.save!
|
|
|
|
|
|
|
|
# Check no notification sent
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly()
|
|
|
|
|
|
|
|
# Now expose category to new user
|
|
|
|
category.set_permissions(Group[:friends] => :full)
|
|
|
|
category.save!
|
|
|
|
|
|
|
|
# Check notification sent
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly('chan1')
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'with tags enabled' do
|
|
|
|
let(:tag){Fabricate(:tag, name:'gsoc')}
|
|
|
|
let(:tagged_topic){Fabricate(:topic, category_id: category.id, tags: [tag])}
|
|
|
|
let(:tagged_first_post) {Fabricate(:post, topic: tagged_topic)}
|
|
|
|
|
|
|
|
before(:each) do
|
|
|
|
SiteSetting.tagging_enabled = true
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should still work for rules without any tags specified' do
|
2017-06-29 12:50:54 -04:00
|
|
|
create_rule('dummy', 'chan1', 'watch', category.id, nil)
|
2017-06-27 14:21:27 -04:00
|
|
|
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
manager.trigger_notifications(tagged_first_post.id)
|
|
|
|
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly('chan1','chan1')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should only match tagged topics when rule has tags' do
|
2017-06-29 12:50:54 -04:00
|
|
|
create_rule('dummy', 'chan1', 'watch', category.id, [tag.name])
|
2017-06-27 14:21:27 -04:00
|
|
|
|
|
|
|
manager.trigger_notifications(first_post.id)
|
|
|
|
manager.trigger_notifications(tagged_first_post.id)
|
|
|
|
|
|
|
|
expect(provider.sent_messages.map{|x| x[:channel]}).to contain_exactly('chan1')
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|