FEATURE: allow users to easily track/watch/mute topics via email

If you reply to an email with the word "mute" a topic will be muted
If you reply to an email with the word "track" a topic will be tracked
If you reply to an email with the word "watch" a topic will be watched

These ninja command can help advanced mailing list ex-users, saves a trip
to the website
This commit is contained in:
Sam 2019-03-06 18:38:49 +11:00
parent 8d7c10f7f2
commit b2187301fd
5 changed files with 49 additions and 7 deletions

View File

@ -899,6 +899,22 @@ module Email
create_post_with_attachments(options)
end
def notification_level_for(body)
# since we are stripping save all this work on long replies
return nil if body.length > 40
body = body.strip.downcase
case body
when "mute"
NotificationLevels.topic_levels[:muted]
when "track"
NotificationLevels.topic_levels[:tracking]
when "watch"
NotificationLevels.topic_levels[:watching]
else nil
end
end
def create_reply(options = {})
raise TopicNotFoundError if options[:topic].nil? || options[:topic].trashed?
raise BouncedEmailError if options[:bounce] && options[:topic].archetype != Archetype.private_message
@ -908,6 +924,8 @@ module Email
if post_action_type = post_action_for(options[:raw])
create_post_action(options[:user], options[:post], post_action_type)
elsif notification_level = notification_level_for(options[:raw])
TopicUser.change(options[:user].id, options[:post].topic_id, notification_level: notification_level)
else
raise TopicClosedError if options[:topic].closed?
options[:topic_id] = options[:topic].id

View File

@ -251,6 +251,10 @@ describe Email::Receiver do
)
end
let :topic_user do
TopicUser.find_by(topic_id: topic.id, user_id: user.id)
end
it "uses MD5 of 'mail_string' there is no message_id" do
mail_string = email(:missing_message_id)
expect { Email::Receiver.new(mail_string).process! }.to change { IncomingEmail.count }
@ -285,14 +289,34 @@ describe Email::Receiver do
expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicNotFoundError)
end
it "raises a TopicClosedError when the topic was closed" do
topic.update_columns(closed: true)
expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicClosedError)
end
context "a closed topic" do
it "does not raise TopicClosedError when performing a like action" do
topic.update_columns(closed: true)
expect { process(:like) }.to change(PostAction, :count)
before do
topic.update_columns(closed: true)
end
it "raises a TopicClosedError when the topic was closed" do
expect { process(:reply_user_matching) }.to raise_error(Email::Receiver::TopicClosedError)
end
it "Can watch topics via the watch command" do
# TODO support other locales as well, the tricky thing is that these string live in
# client.yml not on server yml so it is a bit tricky to find
topic.update_columns(closed: true)
process(:watch)
expect(topic_user.notification_level).to eq(NotificationLevels.topic_levels[:watching])
end
it "Can mute topics via the mute command" do
process(:mute)
expect(topic_user.notification_level).to eq(NotificationLevels.topic_levels[:muted])
end
it "can track a topic via the track command" do
process(:track)
expect(topic_user.notification_level).to eq(NotificationLevels.topic_levels[:tracking])
end
end
it "raises an InvalidPost when there was an error while creating the post" do

BIN
spec/fixtures/emails/mute.eml vendored Normal file

Binary file not shown.

BIN
spec/fixtures/emails/track.eml vendored Normal file

Binary file not shown.

BIN
spec/fixtures/emails/watch.eml vendored Normal file

Binary file not shown.