FEATURE: add "email in-reply-to user option"
We no longer include previous replies as "context", instead we include and excerpt of the post being replied to at the bottom of notifications, this information was previously missing. Users may opt in to emailing previous replies if they wish or opt out of "in-reply-to" which makes sense in some email clients that are smarter about displaying a tree of replies.
This commit is contained in:
parent
a01b2a48d5
commit
820a435af8
|
@ -158,6 +158,7 @@ const User = RestModel.extend({
|
||||||
'external_links_in_new_tab',
|
'external_links_in_new_tab',
|
||||||
'email_digests',
|
'email_digests',
|
||||||
'email_direct',
|
'email_direct',
|
||||||
|
'email_in_reply_to',
|
||||||
'email_private_messages',
|
'email_private_messages',
|
||||||
'email_previous_replies',
|
'email_previous_replies',
|
||||||
'dynamic_favicon',
|
'dynamic_favicon',
|
||||||
|
|
|
@ -180,6 +180,7 @@
|
||||||
<label>{{i18n 'user.email_previous_replies.title'}}</label>
|
<label>{{i18n 'user.email_previous_replies.title'}}</label>
|
||||||
{{combo-box valueAttribute="value" content=previousRepliesOptions value=model.user_option.email_previous_replies}}
|
{{combo-box valueAttribute="value" content=previousRepliesOptions value=model.user_option.email_previous_replies}}
|
||||||
</div>
|
</div>
|
||||||
|
{{preference-checkbox labelKey="user.email_in_reply_to" checked=model.user_option.email_in_reply_to}}
|
||||||
{{preference-checkbox labelKey="user.email_private_messages" checked=model.user_option.email_private_messages}}
|
{{preference-checkbox labelKey="user.email_private_messages" checked=model.user_option.email_private_messages}}
|
||||||
{{preference-checkbox labelKey="user.email_direct" checked=model.user_option.email_direct}}
|
{{preference-checkbox labelKey="user.email_direct" checked=model.user_option.email_direct}}
|
||||||
<span class="pref-mailing-list-mode">{{preference-checkbox labelKey="user.mailing_list_mode" checked=model.user_option.mailing_list_mode}}</span>
|
<span class="pref-mailing-list-mode">{{preference-checkbox labelKey="user.mailing_list_mode" checked=model.user_option.mailing_list_mode}}</span>
|
||||||
|
|
|
@ -193,9 +193,9 @@ class UserNotifications < ActionMailer::Base
|
||||||
include UserNotificationsHelper
|
include UserNotificationsHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.get_context_posts(post, topic_user)
|
def self.get_context_posts(post, topic_user, user)
|
||||||
user_option = topic_user.try(:user).try(:user_option)
|
|
||||||
if user_option && (user_option.email_previous_replies == UserOption.previous_replies_type[:never])
|
if user.user_option.email_previous_replies == UserOption.previous_replies_type[:never]
|
||||||
return []
|
return []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ class UserNotifications < ActionMailer::Base
|
||||||
.order('created_at desc')
|
.order('created_at desc')
|
||||||
.limit(SiteSetting.email_posts_context)
|
.limit(SiteSetting.email_posts_context)
|
||||||
|
|
||||||
if topic_user && topic_user.last_emailed_post_number && user_option.try(:email_previous_replies) == UserOption.previous_replies_type[:unless_emailed]
|
if topic_user && topic_user.last_emailed_post_number && user.user_option.email_previous_replies == UserOption.previous_replies_type[:unless_emailed]
|
||||||
context_posts = context_posts.where("post_number > ?", topic_user.last_emailed_post_number)
|
context_posts = context_posts.where("post_number > ?", topic_user.last_emailed_post_number)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ class UserNotifications < ActionMailer::Base
|
||||||
|
|
||||||
context = ""
|
context = ""
|
||||||
tu = TopicUser.get(post.topic_id, user)
|
tu = TopicUser.get(post.topic_id, user)
|
||||||
context_posts = self.class.get_context_posts(post, tu)
|
context_posts = self.class.get_context_posts(post, tu, user)
|
||||||
|
|
||||||
# make .present? cheaper
|
# make .present? cheaper
|
||||||
context_posts = context_posts.to_a
|
context_posts = context_posts.to_a
|
||||||
|
@ -296,11 +296,13 @@ class UserNotifications < ActionMailer::Base
|
||||||
if opts[:use_template_html]
|
if opts[:use_template_html]
|
||||||
topic_excerpt = post.excerpt.gsub("\n", " ") if post.is_first_post? && post.excerpt
|
topic_excerpt = post.excerpt.gsub("\n", " ") if post.is_first_post? && post.excerpt
|
||||||
else
|
else
|
||||||
|
in_reply_to_post = post.reply_to_post if user.user_option.email_in_reply_to
|
||||||
html = UserNotificationRenderer.new(Rails.configuration.paths["app/views"]).render(
|
html = UserNotificationRenderer.new(Rails.configuration.paths["app/views"]).render(
|
||||||
template: 'email/notification',
|
template: 'email/notification',
|
||||||
format: :html,
|
format: :html,
|
||||||
locals: { context_posts: context_posts,
|
locals: { context_posts: context_posts,
|
||||||
post: post,
|
post: post,
|
||||||
|
in_reply_to_post: in_reply_to_post,
|
||||||
classes: RTL.new(user).css_class
|
classes: RTL.new(user).css_class
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,6 +16,7 @@ class UserOption < ActiveRecord::Base
|
||||||
self.automatically_unpin_topics = SiteSetting.default_topics_automatic_unpin
|
self.automatically_unpin_topics = SiteSetting.default_topics_automatic_unpin
|
||||||
self.email_private_messages = SiteSetting.default_email_private_messages
|
self.email_private_messages = SiteSetting.default_email_private_messages
|
||||||
self.email_previous_replies = SiteSetting.default_email_previous_replies
|
self.email_previous_replies = SiteSetting.default_email_previous_replies
|
||||||
|
self.email_in_reply_to = SiteSetting.default_email_in_reply_to
|
||||||
|
|
||||||
self.enable_quoting = SiteSetting.default_other_enable_quoting
|
self.enable_quoting = SiteSetting.default_other_enable_quoting
|
||||||
self.external_links_in_new_tab = SiteSetting.default_other_external_links_in_new_tab
|
self.external_links_in_new_tab = SiteSetting.default_other_external_links_in_new_tab
|
||||||
|
|
|
@ -14,7 +14,8 @@ class UserOptionSerializer < ApplicationSerializer
|
||||||
:edit_history_public,
|
:edit_history_public,
|
||||||
:auto_track_topics_after_msecs,
|
:auto_track_topics_after_msecs,
|
||||||
:new_topic_duration_minutes,
|
:new_topic_duration_minutes,
|
||||||
:email_previous_replies
|
:email_previous_replies,
|
||||||
|
:email_in_reply_to
|
||||||
|
|
||||||
|
|
||||||
def include_edit_history_public?
|
def include_edit_history_public?
|
||||||
|
|
|
@ -21,7 +21,8 @@ class UserUpdater
|
||||||
:digest_after_days,
|
:digest_after_days,
|
||||||
:new_topic_duration_minutes,
|
:new_topic_duration_minutes,
|
||||||
:auto_track_topics_after_msecs,
|
:auto_track_topics_after_msecs,
|
||||||
:email_previous_replies
|
:email_previous_replies,
|
||||||
|
:email_in_reply_to
|
||||||
]
|
]
|
||||||
|
|
||||||
def initialize(actor, user)
|
def initialize(actor, user)
|
||||||
|
@ -53,10 +54,10 @@ class UserUpdater
|
||||||
|
|
||||||
|
|
||||||
save_options = false
|
save_options = false
|
||||||
OPTION_ATTR.each do |attribute|
|
|
||||||
if attributes[attribute].present?
|
|
||||||
save_options = true
|
|
||||||
|
|
||||||
|
OPTION_ATTR.each do |attribute|
|
||||||
|
if attributes.key?(attribute)
|
||||||
|
save_options = true
|
||||||
|
|
||||||
if [true,false].include?(user.user_option.send(attribute))
|
if [true,false].include?(user.user_option.send(attribute))
|
||||||
val = attributes[attribute].to_s == 'true'
|
val = attributes[attribute].to_s == 'true'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<table class='post-wrapper <%= post.whisper? ? "whisper" : "" %>'>
|
<table class='post-wrapper <%= post.whisper? ? "whisper" : "" %> <%= use_excerpt ? "excerpt" : ""%>'>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class='body'><%= format_for_email(post.cooked) %></td>
|
<td class='body'><%= format_for_email(use_excerpt ? post.excerpt : post.cooked) %></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -2,17 +2,22 @@
|
||||||
|
|
||||||
<div class='header-instructions'>%{header_instructions}</div>
|
<div class='header-instructions'>%{header_instructions}</div>
|
||||||
|
|
||||||
<%= render partial: 'email/post', locals: { post: post } %>
|
<%= render partial: 'email/post', locals: { post: post, use_excerpt: false } %>
|
||||||
|
|
||||||
|
<% if in_reply_to_post.present? || context_posts.present? %>
|
||||||
|
<div class='footer'>%{respond_instructions}</div>
|
||||||
|
<hr>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if in_reply_to_post.present? %>
|
||||||
|
<h4 class='.previous-discussion'><%= t "user_notifications.in_reply_to" %></h4>
|
||||||
|
<%= render partial: 'email/post', locals: { post: in_reply_to_post, use_excerpt: true} %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<% if context_posts.present? %>
|
<% if context_posts.present? %>
|
||||||
<div class='footer'>%{respond_instructions}</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<h4 class='.previous-discussion'><%= t "user_notifications.previous_discussion" %></h4>
|
<h4 class='.previous-discussion'><%= t "user_notifications.previous_discussion" %></h4>
|
||||||
|
|
||||||
<% context_posts.each do |p| %>
|
<% context_posts.each do |p| %>
|
||||||
<%= render partial: 'email/post', locals: { post: p } %>
|
<%= render partial: 'email/post', locals: { post: p, use_excerpt: false } %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|
|
@ -628,7 +628,7 @@ en:
|
||||||
website: "Web Site"
|
website: "Web Site"
|
||||||
email_settings: "Email"
|
email_settings: "Email"
|
||||||
email_previous_replies:
|
email_previous_replies:
|
||||||
title: "Include previous replies"
|
title: "Include previous replies at the bottom of emails"
|
||||||
unless_emailed: "unless previously sent"
|
unless_emailed: "unless previously sent"
|
||||||
always: "always"
|
always: "always"
|
||||||
never: "never"
|
never: "never"
|
||||||
|
@ -639,6 +639,7 @@ en:
|
||||||
weekly: "weekly"
|
weekly: "weekly"
|
||||||
every_two_weeks: "every two weeks"
|
every_two_weeks: "every two weeks"
|
||||||
|
|
||||||
|
email_in_reply_to: "Include an excerpt of replied to post in emails"
|
||||||
email_direct: "Send me an email when someone quotes me, replies to my post, mentions my @username, or invites me to a topic"
|
email_direct: "Send me an email when someone quotes me, replies to my post, mentions my @username, or invites me to a topic"
|
||||||
email_private_messages: "Send me an email when someone messages me"
|
email_private_messages: "Send me an email when someone messages me"
|
||||||
email_always: "Send me email notifications even when I am active on the site"
|
email_always: "Send me email notifications even when I am active on the site"
|
||||||
|
|
|
@ -1243,6 +1243,8 @@ en:
|
||||||
default_email_always: "Send an email notification even when the user is active by default."
|
default_email_always: "Send an email notification even when the user is active by default."
|
||||||
default_email_previous_replies: "Include previous replies in emails by default."
|
default_email_previous_replies: "Include previous replies in emails by default."
|
||||||
|
|
||||||
|
default_email_in_reply_to: "Include excerpt of replied to post in emails by default."
|
||||||
|
|
||||||
default_other_new_topic_duration_minutes: "Global default condition for which a topic is considered new."
|
default_other_new_topic_duration_minutes: "Global default condition for which a topic is considered new."
|
||||||
default_other_auto_track_topics_after_msecs: "Global default time before a topic is automatically tracked."
|
default_other_auto_track_topics_after_msecs: "Global default time before a topic is automatically tracked."
|
||||||
default_other_external_links_in_new_tab: "Open external links in a new tab by default."
|
default_other_external_links_in_new_tab: "Open external links in a new tab by default."
|
||||||
|
@ -1995,6 +1997,7 @@ en:
|
||||||
|
|
||||||
user_notifications:
|
user_notifications:
|
||||||
previous_discussion: "Previous Replies"
|
previous_discussion: "Previous Replies"
|
||||||
|
in_reply_to: "In Reply To"
|
||||||
unsubscribe:
|
unsubscribe:
|
||||||
title: "Unsubscribe"
|
title: "Unsubscribe"
|
||||||
description: "Not interested in getting these emails? No problem! Click below to unsubscribe instantly:"
|
description: "Not interested in getting these emails? No problem! Click below to unsubscribe instantly:"
|
||||||
|
|
|
@ -1063,7 +1063,9 @@ user_preferences:
|
||||||
default_email_always: false
|
default_email_always: false
|
||||||
default_email_previous_replies:
|
default_email_previous_replies:
|
||||||
enum: 'PreviousRepliesSiteSetting'
|
enum: 'PreviousRepliesSiteSetting'
|
||||||
default: 1
|
default: 2
|
||||||
|
default_email_in_reply_to:
|
||||||
|
default: true
|
||||||
|
|
||||||
default_other_new_topic_duration_minutes:
|
default_other_new_topic_duration_minutes:
|
||||||
enum: 'NewTopicDurationSiteSetting'
|
enum: 'NewTopicDurationSiteSetting'
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
class AddEmailInReplyToToUserOptions < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :user_options, :email_in_reply_to, :boolean, null: false, default: true
|
||||||
|
change_column :user_options, :email_previous_replies, :integer, default: 2, null: false
|
||||||
|
execute 'UPDATE user_options SET email_previous_replies = 2'
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :user_options, :email_in_reply_to
|
||||||
|
end
|
||||||
|
end
|
|
@ -15,11 +15,16 @@ describe UserNotifications do
|
||||||
_post7 = Fabricate(:post, topic: post1.topic, post_type: Post.types[:whisper])
|
_post7 = Fabricate(:post, topic: post1.topic, post_type: Post.types[:whisper])
|
||||||
last = Fabricate(:post, topic: post1.topic)
|
last = Fabricate(:post, topic: post1.topic)
|
||||||
|
|
||||||
|
post1.user.user_option.email_previous_replies = UserOption.previous_replies_type[:always]
|
||||||
|
|
||||||
# default is only post #1
|
# default is only post #1
|
||||||
expect(UserNotifications.get_context_posts(last, nil).count).to eq(1)
|
expect(UserNotifications.get_context_posts(last, nil, post1.user).count).to eq(1)
|
||||||
# staff members can also see the whisper
|
# staff members can also see the whisper
|
||||||
tu = TopicUser.new(topic: post1.topic, user: build(:moderator))
|
moderator = build(:moderator)
|
||||||
expect(UserNotifications.get_context_posts(last, tu).count).to eq(2)
|
moderator.user_option = UserOption.new
|
||||||
|
moderator.user_option.email_previous_replies = UserOption.previous_replies_type[:always]
|
||||||
|
tu = TopicUser.new(topic: post1.topic, user: moderator)
|
||||||
|
expect(UserNotifications.get_context_posts(last, tu, tu.user).count).to eq(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows users to control context" do
|
it "allows users to control context" do
|
||||||
|
@ -32,13 +37,15 @@ describe UserNotifications do
|
||||||
topic_user = TopicUser.find_by(user_id: user.id, topic_id: post1.topic_id)
|
topic_user = TopicUser.find_by(user_id: user.id, topic_id: post1.topic_id)
|
||||||
# to avoid reloads after update_columns
|
# to avoid reloads after update_columns
|
||||||
user = topic_user.user
|
user = topic_user.user
|
||||||
expect(UserNotifications.get_context_posts(post3, topic_user).count).to eq(1)
|
user.user_option.update_columns(email_previous_replies: UserOption.previous_replies_type[:unless_emailed])
|
||||||
|
|
||||||
|
expect(UserNotifications.get_context_posts(post3, topic_user, user).count).to eq(1)
|
||||||
|
|
||||||
user.user_option.update_columns(email_previous_replies: UserOption.previous_replies_type[:never])
|
user.user_option.update_columns(email_previous_replies: UserOption.previous_replies_type[:never])
|
||||||
expect(UserNotifications.get_context_posts(post3, topic_user).count).to eq(0)
|
expect(UserNotifications.get_context_posts(post3, topic_user, user).count).to eq(0)
|
||||||
|
|
||||||
user.user_option.update_columns(email_previous_replies: UserOption.previous_replies_type[:always])
|
user.user_option.update_columns(email_previous_replies: UserOption.previous_replies_type[:always])
|
||||||
expect(UserNotifications.get_context_posts(post3, topic_user).count).to eq(2)
|
expect(UserNotifications.get_context_posts(post3, topic_user, user).count).to eq(2)
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -110,12 +117,14 @@ describe UserNotifications do
|
||||||
let(:response_by_user) { Fabricate(:user, name: "John Doe") }
|
let(:response_by_user) { Fabricate(:user, name: "John Doe") }
|
||||||
let(:category) { Fabricate(:category, name: 'India') }
|
let(:category) { Fabricate(:category, name: 'India') }
|
||||||
let(:topic) { Fabricate(:topic, category: category) }
|
let(:topic) { Fabricate(:topic, category: category) }
|
||||||
let(:post) { Fabricate(:post, topic: topic) }
|
let(:post) { Fabricate(:post, topic: topic, raw: 'This is My super duper cool topic') }
|
||||||
let(:response) { Fabricate(:post, topic: post.topic, user: response_by_user)}
|
let(:response) { Fabricate(:post, reply_to_post_number: 1, topic: post.topic, user: response_by_user)}
|
||||||
let(:user) { Fabricate(:user) }
|
let(:user) { Fabricate(:user) }
|
||||||
let(:notification) { Fabricate(:notification, user: user) }
|
let(:notification) { Fabricate(:notification, user: user) }
|
||||||
|
|
||||||
it 'generates a correct email' do
|
it 'generates a correct email' do
|
||||||
|
|
||||||
|
# Fabricator is not fabricating this ...
|
||||||
SiteSetting.enable_names = true
|
SiteSetting.enable_names = true
|
||||||
SiteSetting.display_name_on_posts = true
|
SiteSetting.display_name_on_posts = true
|
||||||
mail = UserNotifications.user_replied(response.user,
|
mail = UserNotifications.user_replied(response.user,
|
||||||
|
@ -123,25 +132,41 @@ describe UserNotifications do
|
||||||
notification_type: notification.notification_type,
|
notification_type: notification.notification_type,
|
||||||
notification_data_hash: notification.data_hash
|
notification_data_hash: notification.data_hash
|
||||||
)
|
)
|
||||||
|
|
||||||
# from should include full user name
|
# from should include full user name
|
||||||
expect(mail[:from].display_names).to eql(['John Doe'])
|
expect(mail[:from].display_names).to eql(['John Doe'])
|
||||||
|
|
||||||
# subject should include category name
|
# subject should include category name
|
||||||
expect(mail.subject).to match(/India/)
|
expect(mail.subject).to match(/India/)
|
||||||
|
|
||||||
|
mail_html = mail.html_part.to_s
|
||||||
|
|
||||||
|
expect(mail_html.scan(/My super duper cool topic/).count).to eq(1)
|
||||||
|
expect(mail_html.scan(/In Reply To/).count).to eq(1)
|
||||||
|
|
||||||
# 2 "visit topic" link
|
# 2 "visit topic" link
|
||||||
expect(mail.html_part.to_s.scan(/Visit Topic/).count).to eq(2)
|
expect(mail_html.scan(/Visit Topic/).count).to eq(2)
|
||||||
|
|
||||||
# 2 respond to links cause we have 1 context post
|
# 2 respond to links cause we have 1 context post
|
||||||
expect(mail.html_part.to_s.scan(/to respond/).count).to eq(2)
|
expect(mail_html.scan(/to respond/).count).to eq(2)
|
||||||
|
|
||||||
# 1 unsubscribe
|
# 1 unsubscribe
|
||||||
expect(mail.html_part.to_s.scan(/To unsubscribe/).count).to eq(1)
|
expect(mail_html.scan(/To unsubscribe/).count).to eq(1)
|
||||||
|
|
||||||
# side effect, topic user is updated with post number
|
# side effect, topic user is updated with post number
|
||||||
tu = TopicUser.get(post.topic_id, response.user)
|
tu = TopicUser.get(post.topic_id, response.user)
|
||||||
expect(tu.last_emailed_post_number).to eq(response.post_number)
|
expect(tu.last_emailed_post_number).to eq(response.post_number)
|
||||||
|
|
||||||
|
|
||||||
|
# no In Reply To if user opts out
|
||||||
|
response.user.user_option.email_in_reply_to = false
|
||||||
|
mail = UserNotifications.user_replied(response.user,
|
||||||
|
post: response,
|
||||||
|
notification_type: notification.notification_type,
|
||||||
|
notification_data_hash: notification.data_hash
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
expect(mail.html_part.to_s.scan(/In Reply To/).count).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -169,8 +194,8 @@ describe UserNotifications do
|
||||||
# subject should not include category name
|
# subject should not include category name
|
||||||
expect(mail.subject).not_to match(/Uncategorized/)
|
expect(mail.subject).not_to match(/Uncategorized/)
|
||||||
|
|
||||||
# 2 respond to links cause we have 1 context post
|
# 1 respond to links as no context by default
|
||||||
expect(mail.html_part.to_s.scan(/to respond/).count).to eq(2)
|
expect(mail.html_part.to_s.scan(/to respond/).count).to eq(1)
|
||||||
|
|
||||||
# 1 unsubscribe link
|
# 1 unsubscribe link
|
||||||
expect(mail.html_part.to_s.scan(/To unsubscribe/).count).to eq(1)
|
expect(mail.html_part.to_s.scan(/To unsubscribe/).count).to eq(1)
|
||||||
|
|
|
@ -48,7 +48,8 @@ describe UserUpdater do
|
||||||
mailing_list_mode: true,
|
mailing_list_mode: true,
|
||||||
digest_after_days: "8",
|
digest_after_days: "8",
|
||||||
new_topic_duration_minutes: 100,
|
new_topic_duration_minutes: 100,
|
||||||
auto_track_topics_after_msecs: 101
|
auto_track_topics_after_msecs: 101,
|
||||||
|
email_in_reply_to: false
|
||||||
)
|
)
|
||||||
user.reload
|
user.reload
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@ describe UserUpdater do
|
||||||
expect(user.user_option.digest_after_days).to eq 8
|
expect(user.user_option.digest_after_days).to eq 8
|
||||||
expect(user.user_option.new_topic_duration_minutes).to eq 100
|
expect(user.user_option.new_topic_duration_minutes).to eq 100
|
||||||
expect(user.user_option.auto_track_topics_after_msecs).to eq 101
|
expect(user.user_option.auto_track_topics_after_msecs).to eq 101
|
||||||
|
expect(user.user_option.email_in_reply_to).to eq false
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when update succeeds' do
|
context 'when update succeeds' do
|
||||||
|
|
Loading…
Reference in New Issue