diff --git a/app/assets/javascripts/discourse/controllers/preferences/emails.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/emails.js.es6 index a8ee91590dd..a54e9055438 100644 --- a/app/assets/javascripts/discourse/controllers/preferences/emails.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences/emails.js.es6 @@ -2,15 +2,29 @@ import PreferencesTabController from "discourse/mixins/preferences-tab-controlle import { default as computed } from "ember-addons/ember-computed-decorators"; import { popupAjaxError } from "discourse/lib/ajax-error"; +const EMAIL_LEVELS = { + ALWAYS: 0, + ONLY_WHEN_AWAY: 1, + NEVER: 2 +}; + export default Ember.Controller.extend(PreferencesTabController, { + emailMessagesLevelAway: Ember.computed.equal( + "model.user_option.email_messages_level", + EMAIL_LEVELS.ONLY_WHEN_AWAY + ), + emailLevelAway: Ember.computed.equal( + "model.user_option.email_level", + EMAIL_LEVELS.ONLY_WHEN_AWAY + ), + saveAttrNames: [ - "email_always", + "email_level", + "email_messages_level", "mailing_list_mode", "mailing_list_mode_frequency", "email_digests", - "email_direct", "email_in_reply_to", - "email_private_messages", "email_previous_replies", "digest_after_minutes", "include_tl0_in_digests" @@ -42,6 +56,15 @@ export default Ember.Controller.extend(PreferencesTabController, { { name: I18n.t("user.email_previous_replies.never"), value: 2 } ], + emailLevelOptions: [ + { name: I18n.t("user.email_level.always"), value: EMAIL_LEVELS.ALWAYS }, + { + name: I18n.t("user.email_level.only_when_away"), + value: EMAIL_LEVELS.ONLY_WHEN_AWAY + }, + { name: I18n.t("user.email_level.never"), value: EMAIL_LEVELS.NEVER } + ], + digestFrequencies: [ { name: I18n.t("user.email_digests.every_30_minutes"), value: 30 }, { name: I18n.t("user.email_digests.every_hour"), value: 60 }, @@ -51,6 +74,17 @@ export default Ember.Controller.extend(PreferencesTabController, { { name: I18n.t("user.email_digests.every_two_weeks"), value: 20160 } ], + @computed() + emailFrequencyInstructions() { + if (this.siteSettings.email_time_window_mins) { + return I18n.t("user.email.frequency", { + count: this.siteSettings.email_time_window_mins + }); + } else { + return I18n.t("user.email.frequency_immediately"); + } + }, + actions: { save() { this.set("saved", false); diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6 index 2e5fa5d2f7f..8335d620c74 100644 --- a/app/assets/javascripts/discourse/models/user.js.es6 +++ b/app/assets/javascripts/discourse/models/user.js.es6 @@ -264,14 +264,13 @@ const User = RestModel.extend({ ); let userOptionFields = [ - "email_always", "mailing_list_mode", "mailing_list_mode_frequency", "external_links_in_new_tab", "email_digests", - "email_direct", "email_in_reply_to", - "email_private_messages", + "email_messages_level", + "email_level", "email_previous_replies", "dynamic_favicon", "enable_quoting", diff --git a/app/assets/javascripts/discourse/templates/preferences/emails.hbs b/app/assets/javascripts/discourse/templates/preferences/emails.hbs index b705f0aff1e..780a64dd2ce 100644 --- a/app/assets/javascripts/discourse/templates/preferences/emails.hbs +++ b/app/assets/javascripts/discourse/templates/preferences/emails.hbs @@ -7,23 +7,35 @@ {{/unless}}
+ +
+ + {{combo-box valueAttribute="value" + content=emailLevelOptions + value=model.user_option.email_messages_level + id="user-email-messages-level"}} + {{#if emailMessagesLevelAway}} +
{{emailFrequencyInstructions}}
+ {{/if}} +
+ +
+ + {{combo-box valueAttribute="value" + content=emailLevelOptions + value=model.user_option.email_level + id="user-email-level"}} + {{#if emailLevelAway}} +
{{emailFrequencyInstructions}}
+ {{/if}} +
+
{{combo-box valueAttribute="value" content=previousRepliesOptions value=model.user_option.email_previous_replies}}
{{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_direct" checked=model.user_option.email_direct}} - {{preference-checkbox labelKey="user.email_always" checked=model.user_option.email_always}} - {{#unless model.user_option.email_always}} -
- {{#if siteSettings.email_time_window_mins}} - {{i18n 'user.email.frequency' count=siteSettings.email_time_window_mins}} - {{else}} - {{i18n 'user.email.frequency_immediately'}} - {{/if}} -
- {{/unless}} + {{plugin-outlet name="user-preferences-emails-pref-email-settings" args=(hash model=model save=(action "save"))}}
diff --git a/app/controllers/email_controller.rb b/app/controllers/email_controller.rb index 644876248f6..b4c8f0b7497 100644 --- a/app/controllers/email_controller.rb +++ b/app/controllers/email_controller.rb @@ -91,10 +91,9 @@ class EmailController < ApplicationController end if params["unsubscribe_all"] - user.user_option.update_columns(email_always: false, - email_digests: false, - email_direct: false, - email_private_messages: false) + user.user_option.update_columns(email_digests: false, + email_level: UserOption.email_level_types[:never], + email_messages_level: UserOption.email_level_types[:never]) updated = true end diff --git a/app/jobs/regular/user_email.rb b/app/jobs/regular/user_email.rb index 322d9c01d8d..7a3d089f8cb 100644 --- a/app/jobs/regular/user_email.rb +++ b/app/jobs/regular/user_email.rb @@ -102,7 +102,7 @@ module Jobs return if user.staged && type.to_s == "digest" seen_recently = (user.last_seen_at.present? && user.last_seen_at > SiteSetting.email_time_window_mins.minutes.ago) - seen_recently = false if user.user_option.email_always || user.staged + seen_recently = false if always_email_regular?(user, type) || always_email_private_message?(user, type) || user.staged email_args = {} @@ -133,7 +133,7 @@ module Jobs return [nil, nil] end - unless user.user_option.email_always? + unless always_email_regular?(user, type) || always_email_private_message?(user, type) if (notification && notification.read?) || (post && post.seen?(user)) return skip_message(SkippedEmailLog.reason_types[:user_email_notification_already_read]) end @@ -217,7 +217,7 @@ module Jobs return SkippedEmailLog.reason_types[:user_email_user_suspended] end - already_read = !user.user_option.email_always? && PostTiming.exists?(topic_id: post.topic_id, post_number: post.post_number, user_id: user.id) + already_read = user.user_option.email_level != UserOption.email_level_types[:always] && PostTiming.exists?(topic_id: post.topic_id, post_number: post.post_number, user_id: user.id) if already_read return SkippedEmailLog.reason_types[:user_email_already_read] end @@ -236,6 +236,13 @@ module Jobs ) end + def always_email_private_message?(user, type) + type == :user_private_message && user.user_option.email_messages_level == UserOption.email_level_types[:always] + end + + def always_email_regular?(user, type) + type != :user_private_message && user.user_option.email_level == UserOption.email_level_types[:always] + end end end diff --git a/app/models/email_level_site_setting.rb b/app/models/email_level_site_setting.rb new file mode 100644 index 00000000000..3e368736a2d --- /dev/null +++ b/app/models/email_level_site_setting.rb @@ -0,0 +1,22 @@ +require_dependency 'enum_site_setting' + +class EmailLevelSiteSetting < EnumSiteSetting + + def self.valid_value?(val) + val.to_i.to_s == val.to_s && + values.any? { |v| v[:value] == val.to_i } + end + + def self.values + @values ||= [ + { name: 'user.email_level.always', value: 0 }, + { name: 'user.email_level.only_when_away', value: 1 }, + { name: 'user.email_level.never', value: 2 }, + ] + end + + def self.translate_names? + true + end + +end diff --git a/app/models/user_option.rb b/app/models/user_option.rb index dafcec78b06..2feaba0b4bd 100644 --- a/app/models/user_option.rb +++ b/app/models/user_option.rb @@ -29,15 +29,20 @@ class UserOption < ActiveRecord::Base @text_sizes ||= Enum.new(normal: 0, larger: 1, largest: 2, smaller: 3) end + def self.email_level_types + @email_level_type ||= Enum.new(always: 0, only_when_away: 1, never: 2) + end + validates :text_size_key, inclusion: { in: UserOption.text_sizes.values } + validates :email_level, inclusion: { in: UserOption.email_level_types.values } + validates :email_messages_level, inclusion: { in: UserOption.email_level_types.values } def set_defaults - self.email_always = SiteSetting.default_email_always self.mailing_list_mode = SiteSetting.default_email_mailing_list_mode self.mailing_list_mode_frequency = SiteSetting.default_email_mailing_list_mode_frequency - self.email_direct = SiteSetting.default_email_direct + self.email_level = SiteSetting.default_email_level + self.email_messages_level = SiteSetting.default_email_messages_level self.automatically_unpin_topics = SiteSetting.default_topics_automatic_unpin - self.email_private_messages = SiteSetting.default_email_personal_messages self.email_previous_replies = SiteSetting.default_email_previous_replies self.email_in_reply_to = SiteSetting.default_email_in_reply_to @@ -173,11 +178,10 @@ end # Table name: user_options # # user_id :integer not null, primary key -# email_always :boolean default(FALSE), not null # mailing_list_mode :boolean default(FALSE), not null # email_digests :boolean -# email_direct :boolean default(TRUE), not null -# email_private_messages :boolean default(TRUE), not null +# email_level :integer default(1), not null +# email_messages_level :integer default(0), not null # external_links_in_new_tab :boolean default(FALSE), not null # enable_quoting :boolean default(TRUE), not null # dynamic_favicon :boolean default(FALSE), not null diff --git a/app/serializers/user_option_serializer.rb b/app/serializers/user_option_serializer.rb index d7797c3a0f4..70b51e181c7 100644 --- a/app/serializers/user_option_serializer.rb +++ b/app/serializers/user_option_serializer.rb @@ -1,11 +1,10 @@ class UserOptionSerializer < ApplicationSerializer attributes :user_id, - :email_always, :mailing_list_mode, :mailing_list_mode_frequency, :email_digests, - :email_private_messages, - :email_direct, + :email_level, + :email_messages_level, :external_links_in_new_tab, :dynamic_favicon, :enable_quoting, diff --git a/app/services/anonymous_shadow_creator.rb b/app/services/anonymous_shadow_creator.rb index d28f89e2103..a5fef713d16 100644 --- a/app/services/anonymous_shadow_creator.rb +++ b/app/services/anonymous_shadow_creator.rb @@ -48,7 +48,7 @@ class AnonymousShadowCreator ) shadow.user_option.update_columns( - email_private_messages: false, + email_messages_level: UserOption.email_level_types[:never], email_digests: false ) diff --git a/app/services/notification_emailer.rb b/app/services/notification_emailer.rb index 099b2030b4a..7d10072af08 100644 --- a/app/services/notification_emailer.rb +++ b/app/services/notification_emailer.rb @@ -67,7 +67,7 @@ class NotificationEmailer EMAILABLE_POST_TYPES ||= Set.new [Post.types[:regular], Post.types[:whisper]] def enqueue(type, delay = default_delay) - return unless notification.user.user_option.email_direct? + return if notification.user.user_option.email_level == UserOption.email_level_types[:never] perform_enqueue(type, delay) end @@ -80,7 +80,7 @@ class NotificationEmailer return end - return unless notification.user.user_option.email_private_messages? + return if notification.user.user_option.email_messages_level == UserOption.email_level_types[:never] perform_enqueue(type, delay) end diff --git a/app/services/user_anonymizer.rb b/app/services/user_anonymizer.rb index dfeb941d8db..bde3d3c6090 100644 --- a/app/services/user_anonymizer.rb +++ b/app/services/user_anonymizer.rb @@ -40,11 +40,10 @@ class UserAnonymizer @user.primary_email.update_attribute(:email, "#{@user.username}@anonymized.invalid") options = @user.user_option - options.email_always = false options.mailing_list_mode = false options.email_digests = false - options.email_private_messages = false - options.email_direct = false + options.email_level = UserOption.email_level_types[:never] + options.email_messages_level = UserOption.email_level_types[:never] options.save! if profile = @user.user_profile diff --git a/app/services/user_updater.rb b/app/services/user_updater.rb index 261634a6f5e..ef73795f005 100644 --- a/app/services/user_updater.rb +++ b/app/services/user_updater.rb @@ -15,12 +15,11 @@ class UserUpdater } OPTION_ATTR = [ - :email_always, :mailing_list_mode, :mailing_list_mode_frequency, :email_digests, - :email_direct, - :email_private_messages, + :email_level, + :email_messages_level, :external_links_in_new_tab, :enable_quoting, :dynamic_favicon, diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index d7c57975b36..3a30ada298c 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -950,12 +950,14 @@ en: every_three_days: "every three days" weekly: "weekly" every_two_weeks: "every two weeks" - + email_level: + title: "Send me an email when someone quotes me, replies to my post, mentions my @username, or invites me to a topic" + always: "always" + only_when_away: "only when away" + never: "never" + email_messages_level: "Send me an email when someone messages me" include_tl0_in_digests: "Include content from new users in summary emails" 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_private_messages: "Send me an email when someone messages me" - email_always: "Send me email notifications even when I am active on the site" other_settings: "Other" categories_settings: "Categories" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 61d3777b15d..d028f80f529 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -873,7 +873,7 @@ en: user_must_edit: "

This post was flagged by the community and is temporarily hidden.

" ignored: - hidden_content: '

Hidden content

' + hidden_content: "

Hidden content

" archetypes: regular: @@ -1921,12 +1921,11 @@ en: default_email_digest_frequency: "How often users receive summary emails by default." default_include_tl0_in_digests: "Include posts from new users in summary emails by default. Users can change this in their preferences." - default_email_personal_messages: "Send an email when someone messages the user by default." - default_email_direct: "Send an email when someone quotes/replies to/mentions or invites the user by default." + default_email_level: "Set default email notification level when someone quotes/replies to/mentions or invites user." + default_email_messages_level: "Set default email notification level when someone messages user." default_email_mailing_list_mode: "Send an email for every new post by default." default_email_mailing_list_mode_frequency: "Users who enable mailing list mode will receive emails this often by default." disable_mailing_list_mode: "Disallow users from enabling mailing list mode." - 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_in_reply_to: "Include excerpt of replied to post in emails by default." diff --git a/config/site_settings.yml b/config/site_settings.yml index 45860c63a6b..5ce10ac3d48 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -1814,8 +1814,12 @@ user_preferences: enum: "DigestEmailSiteSetting" default: 10080 default_include_tl0_in_digests: false - default_email_personal_messages: true - default_email_direct: true + default_email_level: + enum: "EmailLevelSiteSetting" + default: 1 + default_email_messages_level: + enum: "EmailLevelSiteSetting" + default: 0 default_email_mailing_list_mode: false default_email_mailing_list_mode_frequency: enum: "MailingListModeSiteSetting" @@ -1823,7 +1827,6 @@ user_preferences: disable_mailing_list_mode: default: false client: true - default_email_always: false default_email_previous_replies: enum: "PreviousRepliesSiteSetting" default: 2 diff --git a/db/fixtures/009_users.rb b/db/fixtures/009_users.rb index a2ca6f7dda0..add14131819 100644 --- a/db/fixtures/009_users.rb +++ b/db/fixtures/009_users.rb @@ -27,8 +27,8 @@ User.seed do |u| end UserOption.where(user_id: -1).update_all( - email_private_messages: false, - email_direct: false + email_messages_level: UserOption.email_level_types[:never], + email_level: UserOption.email_level_types[:never] ) Group.user_trust_level_change!(-1, TrustLevel[4]) @@ -55,9 +55,9 @@ if ENV["SMOKE"] == "1" end.first UserOption.where(user_id: smoke_user.id).update_all( - email_direct: false, email_digests: false, - email_private_messages: false, + email_messages_level: UserOption.email_level_types[:never], + email_level: UserOption.email_level_types[:never] ) EmailToken.where(user_id: smoke_user.id).update_all(confirmed: true) diff --git a/db/migrate/20190312181641_migrate_email_user_options.rb b/db/migrate/20190312181641_migrate_email_user_options.rb new file mode 100644 index 00000000000..05ed0c1489b --- /dev/null +++ b/db/migrate/20190312181641_migrate_email_user_options.rb @@ -0,0 +1,29 @@ +class MigrateEmailUserOptions < ActiveRecord::Migration[5.2] + def up + # see UserOption.email_level_types + # always = 0, only_while_away: 1, never: 2 + + add_column :user_options, :email_level, :integer, default: 1, null: false + add_column :user_options, :email_messages_level, :integer, default: 0, null: false + + execute <<~SQL + UPDATE user_options + SET email_level = CASE + WHEN email_direct AND email_always + THEN 0 + WHEN email_direct AND email_always IS NOT TRUE + THEN 1 + ELSE 2 + END, + email_messages_level = CASE + WHEN email_private_messages + THEN 0 + ELSE 2 + END + SQL + end + + def down + # See postmigration: 20190312194528_drop_email_user_options_columns.rb + end +end diff --git a/db/migrate/20190313134642_migrate_default_user_email_options.rb b/db/migrate/20190313134642_migrate_default_user_email_options.rb new file mode 100644 index 00000000000..974e146dee2 --- /dev/null +++ b/db/migrate/20190313134642_migrate_default_user_email_options.rb @@ -0,0 +1,34 @@ +class MigrateDefaultUserEmailOptions < ActiveRecord::Migration[5.2] + def up + # see UserOption.email_level_types + # always = 0, only_while_away: 1, never: 2 + + email_always = DB.query_single("SELECT value FROM site_settings WHERE name = 'default_email_always'").first + email_direct = DB.query_single("SELECT value FROM site_settings WHERE name = 'default_email_direct'").first + email_personal_messages = DB.query_single("SELECT value FROM site_settings WHERE name = 'default_email_personal_messages'").first + + default_email_level = nil + default_email_level = 0 if email_direct != 'f' && email_always == 't' + default_email_level = 2 if email_direct == 'f' + + unless default_email_level.nil? + execute "INSERT INTO site_settings (name, data_type, value, created_at, updated_at) + VALUES ('default_email_level', 7, #{default_email_level}, now(), now())" + end + + default_email_messages_level = nil + default_email_messages_level = 0 if email_personal_messages != 'f' && email_always == 't' + default_email_messages_level = 2 if email_personal_messages == 'f' + + unless default_email_messages_level.nil? + execute "INSERT INTO site_settings (name, data_type, value, created_at, updated_at) + VALUES ('default_email_messages_level', 7, #{default_email_messages_level}, now(), now())" + end + + execute "DELETE from site_settings where name in ('default_email_always', 'default_email_direct', 'default_email_personal_messages')" + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/post_migrate/20190312194528_drop_email_user_options_columns.rb b/db/post_migrate/20190312194528_drop_email_user_options_columns.rb new file mode 100644 index 00000000000..bc901c40fc6 --- /dev/null +++ b/db/post_migrate/20190312194528_drop_email_user_options_columns.rb @@ -0,0 +1,19 @@ +require 'migration/column_dropper' + +class DropEmailUserOptionsColumns < ActiveRecord::Migration[5.2] + def up + { + user_options: %i{ + email_direct + email_private_messages + email_always + }, + }.each do |table, columns| + Migration::ColumnDropper.execute_drop(table, columns) + end + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/lib/email/receiver.rb b/lib/email/receiver.rb index c7f706d05c2..e8b5ac56297 100644 --- a/lib/email/receiver.rb +++ b/lib/email/receiver.rb @@ -1154,8 +1154,8 @@ module Email def enable_email_pm_setting(user) # ensure user PM emails are enabled (since user is posting via email) - if !user.staged && !user.user_option.email_private_messages - user.user_option.update!(email_private_messages: true) + if !user.staged && user.user_option.email_messages_level == UserOption.email_level_types[:never] + user.user_option.update!(email_messages_level: UserOption.email_level_types[:always]) end end end diff --git a/plugins/discourse-narrative-bot/db/fixtures/001_discobot.rb b/plugins/discourse-narrative-bot/db/fixtures/001_discobot.rb index 4bf346baa5b..64dc3ebc84f 100644 --- a/plugins/discourse-narrative-bot/db/fixtures/001_discobot.rb +++ b/plugins/discourse-narrative-bot/db/fixtures/001_discobot.rb @@ -50,8 +50,8 @@ end bot.update!(admin: true, moderator: false) bot.user_option.update!( - email_private_messages: false, - email_direct: false + email_messages_level: UserOption.email_level_types[:never], + email_level: UserOption.email_level_types[:never] ) if !bot.user_profile.bio_raw diff --git a/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/track_selector_spec.rb b/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/track_selector_spec.rb index b023b935411..027d2fc4dbe 100644 --- a/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/track_selector_spec.rb +++ b/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/track_selector_spec.rb @@ -109,7 +109,7 @@ describe DiscourseNarrativeBot::TrackSelector do it 'should not enqueue any user email' do NotificationEmailer.enable - user.user_option.update!(email_always: true) + user.user_option.update!(email_level: UserOption.email_level_types[:always]) post.update!( raw: 'show me what you can do', diff --git a/script/import_scripts/base.rb b/script/import_scripts/base.rb index 39d20568467..454b88395a1 100644 --- a/script/import_scripts/base.rb +++ b/script/import_scripts/base.rb @@ -372,9 +372,8 @@ class ImportScripts::Base user_option = u.user_option user_option.email_digests = false - user_option.email_private_messages = false - user_option.email_direct = false - user_option.email_always = false + user_option.email_level = UserOption.email_level_types[:never] + user_option.email_messages_level = UserOption.email_level_types[:never] user_option.save! if u.save StaffActionLogger.new(Discourse.system_user).log_user_suspend(u, ban_reason) diff --git a/script/import_scripts/ipboard.rb b/script/import_scripts/ipboard.rb index 316aa983bea..2f936215be9 100644 --- a/script/import_scripts/ipboard.rb +++ b/script/import_scripts/ipboard.rb @@ -246,9 +246,8 @@ EOM user_option = user.user_option user_option.email_digests = false - user_option.email_private_messages = false - user_option.email_direct = false - user_option.email_always = false + user_option.email_level = UserOption.email_level_types[:never] + user_option.email_messages_level = UserOption.email_level_types[:never] user_option.save! if user.save diff --git a/script/import_scripts/phpbb3/importers/user_importer.rb b/script/import_scripts/phpbb3/importers/user_importer.rb index 97b37776d48..1af3f38a5d8 100644 --- a/script/import_scripts/phpbb3/importers/user_importer.rb +++ b/script/import_scripts/phpbb3/importers/user_importer.rb @@ -93,9 +93,8 @@ module ImportScripts::PhpBB3 if disable_email user_option = user.user_option user_option.email_digests = false - user_option.email_private_messages = false - user_option.email_direct = false - user_option.email_always = false + user_option.email_level = UserOption.email_level_types[:never] + user_option.email_messages_level = UserOption.email_level_types[:never] user_option.save! end diff --git a/spec/components/email/receiver_spec.rb b/spec/components/email/receiver_spec.rb index a87629e00f6..dbdc5082fc8 100644 --- a/spec/components/email/receiver_spec.rb +++ b/spec/components/email/receiver_spec.rb @@ -631,15 +631,15 @@ describe Email::Receiver do expect { process(:reply_user_not_matching_but_known) }.to change { topic.posts.count } end - it "re-enables user's email_private_messages setting when user replies to a private topic" do + it "re-enables user's PM email notifications when user replies to a private topic" do topic.update_columns(category_id: nil, archetype: Archetype.private_message) topic.allowed_users << user topic.save - user.user_option.update_columns(email_private_messages: false) + user.user_option.update_columns(email_messages_level: UserOption.email_level_types[:never]) expect { process(:reply_user_matching) }.to change { topic.posts.count } user.reload - expect(user.user_option.email_private_messages).to eq(true) + expect(user.user_option.email_messages_level).to eq(UserOption.email_level_types[:always]) end end @@ -741,12 +741,12 @@ describe Email::Receiver do expect(Post.last.uploads.length).to eq 1 end - it "enables user's email_private_messages setting when user emails new topic to group" do + it "reenables user's PM email notifications when user emails new topic to group" do user = Fabricate(:user, email: "existing@bar.com") - user.user_option.update_columns(email_private_messages: false) + user.user_option.update_columns(email_messages_level: UserOption.email_level_types[:never]) expect { process(:group_existing_user) }.to change(Topic, :count) user.reload - expect(user.user_option.email_private_messages).to eq(true) + expect(user.user_option.email_messages_level).to eq(UserOption.email_level_types[:always]) end context "with forwarded emails enabled" do diff --git a/spec/jobs/enqueue_digest_emails_spec.rb b/spec/jobs/enqueue_digest_emails_spec.rb index c729c991383..63d97c9e8e9 100644 --- a/spec/jobs/enqueue_digest_emails_spec.rb +++ b/spec/jobs/enqueue_digest_emails_spec.rb @@ -73,7 +73,7 @@ describe Jobs::EnqueueDigestEmails do context 'visited the site this week' do let(:user_visited_this_week) { Fabricate(:active_user, last_seen_at: 6.days.ago) } - let(:user_visited_this_week_email_always) { Fabricate(:active_user, last_seen_at: 6.days.ago, email_always: true) } + let(:user_visited_this_week_email_always) { Fabricate(:active_user, last_seen_at: 6.days.ago, email_level: UserOption.email_level_types[:always]) } it "doesn't return users who have been emailed recently" do user = user_visited_this_week diff --git a/spec/jobs/user_email_spec.rb b/spec/jobs/user_email_spec.rb index 0a05e4ccde4..f45d723e9fd 100644 --- a/spec/jobs/user_email_spec.rb +++ b/spec/jobs/user_email_spec.rb @@ -91,6 +91,71 @@ describe Jobs::UserEmail do end end + context "recently seen" do + let(:post) { Fabricate(:post, user: user) } + let(:notification) { Fabricate( + :notification, + user: user, + topic: post.topic, + post_number: post.post_number, + data: { original_post_id: post.id }.to_json + ) + } + before do + user.update_column(:last_seen_at, 9.minutes.ago) + end + + it "doesn't send an email to a user that's been recently seen" do + Jobs::UserEmail.new.execute(type: :user_replied, user_id: user.id, post_id: post.id) + expect(ActionMailer::Base.deliveries).to eq([]) + end + + it "does send an email to a user that's been recently seen but has email_level set to always" do + user.user_option.update_attributes(email_level: UserOption.email_level_types[:always]) + PostTiming.create!(topic_id: post.topic_id, post_number: post.post_number, user_id: user.id, msecs: 100) + + Jobs::UserEmail.new.execute( + type: :user_replied, + user_id: user.id, + post_id: post.id, + notification_id: notification.id + ) + + expect(ActionMailer::Base.deliveries.first.to).to contain_exactly( + user.email + ) + end + + it "sends an email by default for a PM to a user that's been recently seen" do + Jobs::UserEmail.new.execute( + type: :user_private_message, + user_id: user.id, + post_id: post.id, + notification_id: notification.id + ) + + expect(ActionMailer::Base.deliveries.first.to).to contain_exactly( + user.email + ) + end + + it "doesn't send a PM email to a user that's been recently seen and has email_messages_level set to never" do + user.user_option.update_attributes(email_messages_level: UserOption.email_level_types[:never]) + user.user_option.update_attributes(email_level: UserOption.email_level_types[:always]) + Jobs::UserEmail.new.execute(type: :user_private_message, user_id: user.id, post_id: post.id) + + expect(ActionMailer::Base.deliveries).to eq([]) + end + + it "doesn't send a regular post email to a user that's been recently seen and has email_level set to never" do + user.user_option.update_attributes(email_messages_level: UserOption.email_level_types[:always]) + user.user_option.update_attributes(email_level: UserOption.email_level_types[:never]) + Jobs::UserEmail.new.execute(type: :user_replied, user_id: user.id, post_id: post.id) + + expect(ActionMailer::Base.deliveries).to eq([]) + end + end + context "email_log" do let(:post) { Fabricate(:post) } @@ -256,9 +321,9 @@ describe Jobs::UserEmail do )).to eq(true) end - it "does send the email if the notification has been seen but the user is set for email_always" do + it "does send the email if the notification has been seen but user has email_level set to always" do notification.update_column(:read, true) - user.user_option.update_column(:email_always, true) + user.user_option.update_column(:email_level, UserOption.email_level_types[:always]) Jobs::UserEmail.new.execute( type: :user_mentioned, @@ -301,9 +366,9 @@ describe Jobs::UserEmail do expect(ActionMailer::Base.deliveries).to eq([]) end - it "does send an email to a user that's been recently seen but has email_always set" do + it "does send an email to a user that's been recently seen but has email_level set to always" do user.update!(last_seen_at: 9.minutes.ago) - user.user_option.update!(email_always: true) + user.user_option.update!(email_level: UserOption.email_level_types[:always]) Jobs::UserEmail.new.execute( type: :user_replied, diff --git a/spec/models/user_option_spec.rb b/spec/models/user_option_spec.rb index 16b558d37fe..62d40fcdb57 100644 --- a/spec/models/user_option_spec.rb +++ b/spec/models/user_option_spec.rb @@ -11,7 +11,8 @@ describe UserOption do user.reload - expect(user.user_option.email_always).to eq(SiteSetting.default_email_always) + expect(user.user_option.email_level).to eq(SiteSetting.default_email_level) + expect(user.user_option.email_messages_level).to eq(SiteSetting.default_email_messages_level) end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 5e5f0617014..3d1c1b8540d 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -265,8 +265,8 @@ describe User do expect(subject.email_tokens).to be_present expect(subject.user_stat).to be_present expect(subject.user_profile).to be_present - expect(subject.user_option.email_private_messages).to eq(true) - expect(subject.user_option.email_direct).to eq(true) + expect(subject.user_option.email_messages_level).to eq(UserOption.email_level_types[:always]) + expect(subject.user_option.email_level).to eq(UserOption.email_level_types[:only_when_away]) end end @@ -1461,10 +1461,9 @@ describe User do before do SiteSetting.default_email_digest_frequency = 1440 # daily - SiteSetting.default_email_personal_messages = false - SiteSetting.default_email_direct = false + SiteSetting.default_email_level = UserOption.email_level_types[:never] + SiteSetting.default_email_messages_level = UserOption.email_level_types[:never] SiteSetting.default_email_mailing_list_mode = true - SiteSetting.default_email_always = true SiteSetting.default_other_new_topic_duration_minutes = -1 # not viewed SiteSetting.default_other_auto_track_topics_after_msecs = 0 # immediately @@ -1485,16 +1484,15 @@ describe User do it "has overriden preferences" do user = Fabricate(:user) options = user.user_option - expect(options.email_always).to eq(true) expect(options.mailing_list_mode).to eq(true) expect(options.digest_after_minutes).to eq(1440) - expect(options.email_private_messages).to eq(false) + expect(options.email_level).to eq(UserOption.email_level_types[:never]) + expect(options.email_messages_level).to eq(UserOption.email_level_types[:never]) expect(options.external_links_in_new_tab).to eq(true) expect(options.enable_quoting).to eq(false) expect(options.dynamic_favicon).to eq(true) expect(options.disable_jump_reply).to eq(true) expect(options.automatically_unpin_topics).to eq(false) - expect(options.email_direct).to eq(false) expect(options.new_topic_duration_minutes).to eq(-1) expect(options.auto_track_topics_after_msecs).to eq(0) expect(options.notification_level_when_replying).to eq(3) @@ -1518,7 +1516,7 @@ describe User do it "Creates a UserOption row when a user record is created and destroys once done" do user = Fabricate(:user) - expect(user.user_option.email_always).to eq(false) + expect(user.user_option.email_level).to eq(UserOption.email_level_types[:only_when_away]) user_id = user.id user.destroy! diff --git a/spec/requests/email_controller_spec.rb b/spec/requests/email_controller_spec.rb index 3b6a1a8f308..df4be4fe857 100644 --- a/spec/requests/email_controller_spec.rb +++ b/spec/requests/email_controller_spec.rb @@ -15,10 +15,9 @@ RSpec.describe EmailController do user = Fabricate(:user) key = UnsubscribeKey.create_key_for(user, "all") - user.user_option.update_columns(email_always: true, - email_digests: true, - email_direct: true, - email_private_messages: true) + user.user_option.update_columns(email_digests: true, + email_level: UserOption.email_level_types[:never], + email_messages_level: UserOption.email_level_types[:never]) post "/email/unsubscribe/#{key}.json", params: { unsubscribe_all: "1" } @@ -32,11 +31,9 @@ RSpec.describe EmailController do user.user_option.reload - expect(user.user_option.email_always).to eq(false) expect(user.user_option.email_digests).to eq(false) - expect(user.user_option.email_direct).to eq(false) - expect(user.user_option.email_private_messages).to eq(false) - + expect(user.user_option.email_level).to eq(UserOption.email_level_types[:never]) + expect(user.user_option.email_messages_level).to eq(UserOption.email_level_types[:never]) end it 'can disable mailing list' do diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index 81409de3fbe..747df3b8872 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -1494,14 +1494,14 @@ describe UsersController do put "/u/#{user.username}.json", params: { muted_usernames: "", theme_ids: [theme.id], - email_direct: false + email_level: UserOption.email_level_types[:always] } user.reload expect(user.muted_users.pluck(:username).sort).to be_empty expect(user.user_option.theme_ids).to eq([theme.id]) - expect(user.user_option.email_direct).to eq(false) + expect(user.user_option.email_level).to eq(UserOption.email_level_types[:always]) end context 'a locale is chosen that differs from I18n.locale' do diff --git a/spec/services/anonymous_shadow_creator_spec.rb b/spec/services/anonymous_shadow_creator_spec.rb index e658be53b23..99a448ccd62 100644 --- a/spec/services/anonymous_shadow_creator_spec.rb +++ b/spec/services/anonymous_shadow_creator_spec.rb @@ -36,7 +36,7 @@ describe AnonymousShadowCreator do shadow3 = AnonymousShadowCreator.get(user) expect(shadow3.user_option.email_digests).to eq(false) - expect(shadow3.user_option.email_private_messages).to eq(false) + expect(shadow3.user_option.email_messages_level).to eq(UserOption.email_level_types[:never]) expect(shadow2.id).not_to eq(shadow3.id) diff --git a/spec/services/notification_emailer_spec.rb b/spec/services/notification_emailer_spec.rb index a3d60f441ed..746dfb0c0d3 100644 --- a/spec/services/notification_emailer_spec.rb +++ b/spec/services/notification_emailer_spec.rb @@ -78,7 +78,7 @@ describe NotificationEmailer do include_examples "enqueue" it "doesn't enqueue a job if the user has mention emails disabled" do - notification.user.user_option.update_columns(email_direct: false) + notification.user.user_option.update_columns(email_level: UserOption.email_level_types[:never]) Jobs.expects(:enqueue_in).with(delay, :user_email, has_entry(type: type)).never NotificationEmailer.process_notification(notification) end @@ -88,7 +88,7 @@ describe NotificationEmailer do include_examples "enqueue" it "doesn't enqueue a job if the user has private message emails disabled" do - notification.user.user_option.update_columns(email_private_messages: false) + notification.user.user_option.update_columns(email_messages_level: UserOption.email_level_types[:never]) Jobs.expects(:enqueue_in).with(delay, :user_email, has_entry(type: type)).never NotificationEmailer.process_notification(notification) end diff --git a/spec/services/user_anonymizer_spec.rb b/spec/services/user_anonymizer_spec.rb index 70f75ce8a66..aa18688701a 100644 --- a/spec/services/user_anonymizer_spec.rb +++ b/spec/services/user_anonymizer_spec.rb @@ -54,15 +54,15 @@ describe UserAnonymizer do it "turns off all notifications" do user.user_option.update_columns( - email_always: true + email_level: UserOption.email_level_types[:always], + email_messages_level: UserOption.email_level_types[:always] ) make_anonymous user.reload expect(user.user_option.email_digests).to eq(false) - expect(user.user_option.email_private_messages).to eq(false) - expect(user.user_option.email_direct).to eq(false) - expect(user.user_option.email_always).to eq(false) + expect(user.user_option.email_level).to eq(UserOption.email_level_types[:never]) + expect(user.user_option.email_messages_level).to eq(UserOption.email_level_types[:never]) expect(user.user_option.mailing_list_mode).to eq(false) end diff --git a/spec/services/user_updater_spec.rb b/spec/services/user_updater_spec.rb index d4a10da977b..37548183c39 100644 --- a/spec/services/user_updater_spec.rb +++ b/spec/services/user_updater_spec.rb @@ -107,7 +107,7 @@ describe UserUpdater do seq = user.user_option.theme_key_seq val = updater.update(bio_raw: 'my new bio', - email_always: 'true', + email_level: UserOption.email_level_types[:always], mailing_list_mode: true, digest_after_minutes: "45", new_topic_duration_minutes: 100, @@ -123,7 +123,7 @@ describe UserUpdater do user.reload expect(user.user_profile.bio_raw).to eq 'my new bio' - expect(user.user_option.email_always).to eq true + expect(user.user_option.email_level).to eq UserOption.email_level_types[:always] expect(user.user_option.mailing_list_mode).to eq true expect(user.user_option.digest_after_minutes).to eq 45 expect(user.user_option.new_topic_duration_minutes).to eq 100 diff --git a/test/javascripts/fixtures/user_fixtures.js.es6 b/test/javascripts/fixtures/user_fixtures.js.es6 index 203f3a76410..79937a4d263 100644 --- a/test/javascripts/fixtures/user_fixtures.js.es6 +++ b/test/javascripts/fixtures/user_fixtures.js.es6 @@ -168,9 +168,8 @@ export default { can_delete_all_posts: false, locale: "", email_digests: true, - email_private_messages: true, - email_direct: true, - email_always: true, + email_messages_level: 0, + email_level: 1, digest_after_minutes: 10080, mailing_list_mode: false, auto_track_topics_after_msecs: 60000, @@ -2507,12 +2506,11 @@ export default { featured_user_badge_ids: [17], user_option: { user_id: 5, - email_always: false, mailing_list_mode: false, mailing_list_mode_frequency: 1, email_digests: true, - email_private_messages: true, - email_direct: true, + email_messages_level: 0, + email_level: 1, external_links_in_new_tab: false, dynamic_favicon: false, enable_quoting: true,