mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 19:00:32 -06:00
Merge branch 'master' into vdom
This commit is contained in:
commit
e8f76c335a
@ -93,3 +93,30 @@ export function withPluginApi(version, apiCodeCallback, opts) {
|
||||
return apiCodeCallback(api);
|
||||
}
|
||||
}
|
||||
|
||||
// This is backported so plugins in the new format will not raise errors
|
||||
//
|
||||
// To upgrade your plugin for backwards compatibility, you can add code in this
|
||||
// form:
|
||||
//
|
||||
// function newApiCode(api) {
|
||||
// // api.xyz();
|
||||
// }
|
||||
//
|
||||
// function oldCode() {
|
||||
// // your pre-PluginAPI code goes here. You will be able to delete this
|
||||
// // code once the `PluginAPI` has been rolled out to all versions of
|
||||
// // Discourse you want to support.
|
||||
// }
|
||||
//
|
||||
// // `newApiCode` will use API version 0.1, if no API support then
|
||||
// // `oldCode` will be called
|
||||
// withPluginApi('0.1', newApiCode, { noApi: oldCode });
|
||||
//
|
||||
export function withPluginApi(version, apiCodeCallback, opts) {
|
||||
console.warn(`Plugin API v${version} is not supported`);
|
||||
|
||||
if (opts && opts.noApi) {
|
||||
return opts.noApi();
|
||||
}
|
||||
}
|
||||
|
@ -147,25 +147,29 @@ const User = RestModel.extend({
|
||||
'location',
|
||||
'name',
|
||||
'locale',
|
||||
'email_digests',
|
||||
'email_direct',
|
||||
'email_always',
|
||||
'email_private_messages',
|
||||
'dynamic_favicon',
|
||||
'digest_after_days',
|
||||
'new_topic_duration_minutes',
|
||||
'external_links_in_new_tab',
|
||||
'mailing_list_mode',
|
||||
'enable_quoting',
|
||||
'disable_jump_reply',
|
||||
'custom_fields',
|
||||
'user_fields',
|
||||
'muted_usernames',
|
||||
'profile_background',
|
||||
'card_background',
|
||||
'automatically_unpin_topics'
|
||||
'card_background'
|
||||
);
|
||||
|
||||
[ 'email_always',
|
||||
'mailing_list_mode',
|
||||
'external_links_in_new_tab',
|
||||
'email_digests',
|
||||
'email_direct',
|
||||
'email_private_messages',
|
||||
'dynamic_favicon',
|
||||
'enable_quoting',
|
||||
'disable_jump_reply',
|
||||
'automatically_unpin_topics',
|
||||
'digest_after_days'
|
||||
].forEach(s => {
|
||||
data[s] = this.get(`user_option.${s}`);
|
||||
});
|
||||
|
||||
['muted','watched','tracked'].forEach(s => {
|
||||
let cats = this.get(s + 'Categories').map(c => c.get('id'));
|
||||
// HACK: denote lack of categories
|
||||
@ -174,7 +178,7 @@ const User = RestModel.extend({
|
||||
});
|
||||
|
||||
if (!Discourse.SiteSettings.edit_history_visible_to_public) {
|
||||
data['edit_history_public'] = this.get('edit_history_public');
|
||||
data['edit_history_public'] = this.get('user_option.edit_history_public');
|
||||
}
|
||||
|
||||
// TODO: We can remove this when migrated fully to rest model.
|
||||
@ -184,7 +188,7 @@ const User = RestModel.extend({
|
||||
type: 'PUT'
|
||||
}).then(result => {
|
||||
this.set('bio_excerpt', result.user.bio_excerpt);
|
||||
const userProps = this.getProperties('enable_quoting', 'external_links_in_new_tab', 'dynamic_favicon');
|
||||
const userProps = Em.getProperties(this.get('user-option'),'enable_quoting', 'external_links_in_new_tab', 'dynamic_favicon');
|
||||
Discourse.User.current().setProperties(userProps);
|
||||
}).finally(() => {
|
||||
this.set('isSaving', false);
|
||||
|
@ -169,17 +169,17 @@
|
||||
<div class="control-group pref-email-settings">
|
||||
<label class="control-label">{{i18n 'user.email_settings'}}</label>
|
||||
{{#if canReceiveDigest}}
|
||||
{{preference-checkbox labelKey="user.email_digests.title" checked=model.email_digests}}
|
||||
{{#if model.email_digests}}
|
||||
{{preference-checkbox labelKey="user.email_digests.title" checked=model.user_option.email_digests}}
|
||||
{{#if model.user_option.email_digests}}
|
||||
<div class='controls controls-dropdown'>
|
||||
{{combo-box valueAttribute="value" content=digestFrequencies value=model.digest_after_days}}
|
||||
{{combo-box valueAttribute="value" content=digestFrequencies value=model.user_option.digest_after_days}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{preference-checkbox labelKey="user.email_private_messages" checked=model.email_private_messages}}
|
||||
{{preference-checkbox labelKey="user.email_direct" checked=model.email_direct}}
|
||||
<span class="pref-mailing-list-mode">{{preference-checkbox labelKey="user.mailing_list_mode" checked=model.mailing_list_mode}}</span>
|
||||
{{preference-checkbox labelKey="user.email_always" checked=model.email_always}}
|
||||
{{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}}
|
||||
<span class="pref-mailing-list-mode">{{preference-checkbox labelKey="user.mailing_list_mode" checked=model.user_option.mailing_list_mode}}</span>
|
||||
{{preference-checkbox labelKey="user.email_always" checked=model.user_option.email_always}}
|
||||
|
||||
<div class='instructions'>
|
||||
{{#if siteSettings.email_time_window_mins}}
|
||||
@ -209,12 +209,12 @@
|
||||
{{combo-box valueAttribute="value" content=autoTrackDurations value=model.auto_track_topics_after_msecs}}
|
||||
</div>
|
||||
|
||||
{{preference-checkbox labelKey="user.external_links_in_new_tab" checked=model.external_links_in_new_tab}}
|
||||
{{preference-checkbox labelKey="user.enable_quoting" checked=model.enable_quoting}}
|
||||
{{preference-checkbox labelKey="user.dynamic_favicon" checked=model.dynamic_favicon}}
|
||||
{{preference-checkbox labelKey="user.disable_jump_reply" checked=model.disable_jump_reply}}
|
||||
{{preference-checkbox labelKey="user.external_links_in_new_tab" checked=model.user_option.external_links_in_new_tab}}
|
||||
{{preference-checkbox labelKey="user.enable_quoting" checked=model.user_option.enable_quoting}}
|
||||
{{preference-checkbox labelKey="user.dynamic_favicon" checked=model.user_option.dynamic_favicon}}
|
||||
{{preference-checkbox labelKey="user.disable_jump_reply" checked=model.user_option.disable_jump_reply}}
|
||||
{{#unless siteSettings.edit_history_visible_to_public}}
|
||||
{{preference-checkbox labelKey="user.edit_history_public" checked=model.edit_history_public}}
|
||||
{{preference-checkbox labelKey="user.edit_history_public" checked=model.user_option.edit_history_public}}
|
||||
{{/unless}}
|
||||
|
||||
{{plugin-outlet "user-custom-preferences"}}
|
||||
@ -254,7 +254,7 @@
|
||||
{{#if siteSettings.automatically_unpin_topics}}
|
||||
<div class="control-group topics">
|
||||
<label class="control-label">{{i18n 'categories.topics'}}</label>
|
||||
{{preference-checkbox labelKey="user.automatically_unpin_topics" checked=model.automatically_unpin_topics}}
|
||||
{{preference-checkbox labelKey="user.automatically_unpin_topics" checked=model.user_option.automatically_unpin_topics}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
@ -26,7 +26,8 @@ class Admin::EmailTemplatesController < Admin::AdminController
|
||||
"user_notifications.user_invited_to_private_message_pm",
|
||||
"user_notifications.user_invited_to_topic", "user_notifications.user_mentioned",
|
||||
"user_notifications.user_posted", "user_notifications.user_posted_pm",
|
||||
"user_notifications.user_quoted", "user_notifications.user_replied"]
|
||||
"user_notifications.user_quoted", "user_notifications.user_replied",
|
||||
"user_notifications.user_linked"]
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -25,9 +25,12 @@ class EmailController < ApplicationController
|
||||
end
|
||||
|
||||
if params[:from_all]
|
||||
@user.update_columns(email_digests: false, email_direct: false, email_private_messages: false, email_always: false)
|
||||
@user.user_option.update_columns(email_always: false,
|
||||
email_digests: false,
|
||||
email_direct: false,
|
||||
email_private_messages: false)
|
||||
else
|
||||
@user.update_column(:email_digests, false)
|
||||
@user.user_option.update_column(:email_digests, false)
|
||||
end
|
||||
|
||||
@success = true
|
||||
@ -36,7 +39,7 @@ class EmailController < ApplicationController
|
||||
def resubscribe
|
||||
@user = DigestUnsubscribeKey.user_for_key(params[:key])
|
||||
raise Discourse::NotFound unless @user.present?
|
||||
@user.update_column(:email_digests, true)
|
||||
@user.user_option.update_column(:email_digests, true)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -11,7 +11,8 @@ module Jobs
|
||||
|
||||
users =
|
||||
User.activated.not_blocked.not_suspended.real
|
||||
.where(mailing_list_mode: true)
|
||||
.joins(:user_option)
|
||||
.where(user_options: {mailing_list_mode: true})
|
||||
.where('NOT EXISTS(
|
||||
SELECT 1
|
||||
FROM topic_users tu
|
||||
|
@ -62,7 +62,7 @@ module Jobs
|
||||
return if user.staged && type == :digest
|
||||
|
||||
seen_recently = (user.last_seen_at.present? && user.last_seen_at > SiteSetting.email_time_window_mins.minutes.ago)
|
||||
seen_recently = false if user.email_always || user.staged
|
||||
seen_recently = false if user.user_option.email_always || user.staged
|
||||
|
||||
email_args = {}
|
||||
|
||||
@ -85,14 +85,14 @@ module Jobs
|
||||
email_args[:notification_type] = email_args[:notification_type].to_s
|
||||
end
|
||||
|
||||
if user.mailing_list_mode? &&
|
||||
if user.user_option.mailing_list_mode? &&
|
||||
!post.topic.private_message? &&
|
||||
NOTIFICATIONS_SENT_BY_MAILING_LIST.include?(email_args[:notification_type])
|
||||
# no need to log a reason when the mail was already sent via the mailing list job
|
||||
return [nil, nil]
|
||||
end
|
||||
|
||||
unless user.email_always?
|
||||
unless user.user_option.email_always?
|
||||
if (notification && notification.read?) || (post && post.seen?(user))
|
||||
return skip_message(I18n.t('email_log.notification_already_read'))
|
||||
end
|
||||
|
@ -15,8 +15,10 @@ module Jobs
|
||||
def target_user_ids
|
||||
# Users who want to receive emails and haven't been emailed in the last day
|
||||
query = User.real
|
||||
.where(email_digests: true, active: true, staged: false)
|
||||
.where(active: true, staged: false)
|
||||
.joins(:user_option)
|
||||
.not_suspended
|
||||
.where(user_options: {email_digests: true})
|
||||
.where("COALESCE(last_emailed_at, '2010-01-01') <= CURRENT_TIMESTAMP - ('1 DAY'::INTERVAL * digest_after_days)")
|
||||
.where("COALESCE(last_seen_at, '2010-01-01') <= CURRENT_TIMESTAMP - ('1 DAY'::INTERVAL * digest_after_days)")
|
||||
.where("COALESCE(last_seen_at, '2010-01-01') >= CURRENT_TIMESTAMP - ('1 DAY'::INTERVAL * #{SiteSetting.delete_digest_email_after_days})")
|
||||
|
@ -110,6 +110,13 @@ class UserNotifications < ActionMailer::Base
|
||||
notification_email(user, opts)
|
||||
end
|
||||
|
||||
def user_linked(user, opts)
|
||||
opts[:allow_reply_by_email] = true
|
||||
opts[:use_site_subject] = true
|
||||
opts[:show_category_in_subject] = true
|
||||
notification_email(user, opts)
|
||||
end
|
||||
|
||||
def user_mentioned(user, opts)
|
||||
opts[:allow_reply_by_email] = true
|
||||
opts[:use_site_subject] = true
|
||||
@ -314,7 +321,7 @@ class UserNotifications < ActionMailer::Base
|
||||
context: context,
|
||||
username: username,
|
||||
add_unsubscribe_link: !user.staged,
|
||||
add_unsubscribe_via_email_link: user.mailing_list_mode,
|
||||
add_unsubscribe_via_email_link: user.user_option.mailing_list_mode,
|
||||
unsubscribe_url: post.topic.unsubscribe_url,
|
||||
allow_reply_by_email: allow_reply_by_email,
|
||||
use_site_subject: use_site_subject,
|
||||
|
@ -38,6 +38,7 @@ class User < ActiveRecord::Base
|
||||
has_many :user_archived_messages, dependent: :destroy
|
||||
|
||||
|
||||
has_one :user_option, dependent: :destroy
|
||||
has_one :user_avatar, dependent: :destroy
|
||||
has_one :facebook_user_info, dependent: :destroy
|
||||
has_one :twitter_user_info, dependent: :destroy
|
||||
@ -80,6 +81,7 @@ class User < ActiveRecord::Base
|
||||
|
||||
after_create :create_email_token
|
||||
after_create :create_user_stat
|
||||
after_create :create_user_option
|
||||
after_create :create_user_profile
|
||||
after_create :ensure_in_trust_level_group
|
||||
after_create :automatic_group_membership
|
||||
@ -123,7 +125,7 @@ class User < ActiveRecord::Base
|
||||
|
||||
# TODO-PERF: There is no indexes on any of these
|
||||
# and NotifyMailingListSubscribers does a select-all-and-loop
|
||||
# may want to create an index on (active, blocked, suspended_till, mailing_list_mode)?
|
||||
# may want to create an index on (active, blocked, suspended_till)?
|
||||
scope :blocked, -> { where(blocked: true) }
|
||||
scope :not_blocked, -> { where(blocked: false) }
|
||||
scope :suspended, -> { where('suspended_till IS NOT NULL AND suspended_till > ?', Time.zone.now) }
|
||||
@ -911,6 +913,10 @@ class User < ActiveRecord::Base
|
||||
stat.save!
|
||||
end
|
||||
|
||||
def create_user_option
|
||||
UserOption.create(user_id: id)
|
||||
end
|
||||
|
||||
def create_email_token
|
||||
email_tokens.create(email: email)
|
||||
end
|
||||
@ -965,21 +971,8 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def set_default_user_preferences
|
||||
set_default_email_digest_frequency
|
||||
set_default_email_private_messages
|
||||
set_default_email_direct
|
||||
set_default_email_mailing_list_mode
|
||||
set_default_email_always
|
||||
|
||||
set_default_other_new_topic_duration_minutes
|
||||
set_default_other_auto_track_topics_after_msecs
|
||||
set_default_other_external_links_in_new_tab
|
||||
set_default_other_enable_quoting
|
||||
set_default_other_dynamic_favicon
|
||||
set_default_other_disable_jump_reply
|
||||
set_default_other_edit_history_public
|
||||
|
||||
set_default_topics_automatic_unpin
|
||||
|
||||
# needed, otherwise the callback chain is broken...
|
||||
true
|
||||
@ -1031,26 +1024,6 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def set_default_email_digest_frequency
|
||||
if has_attribute?(:email_digests)
|
||||
if SiteSetting.default_email_digest_frequency.to_i <= 0
|
||||
self.email_digests = false
|
||||
else
|
||||
self.email_digests = true
|
||||
self.digest_after_days ||= SiteSetting.default_email_digest_frequency.to_i if has_attribute?(:digest_after_days)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def set_default_email_mailing_list_mode
|
||||
self.mailing_list_mode = SiteSetting.default_email_mailing_list_mode if has_attribute?(:mailing_list_mode)
|
||||
end
|
||||
|
||||
%w{private_messages direct always}.each do |s|
|
||||
define_method("set_default_email_#{s}") do
|
||||
self.send("email_#{s}=", SiteSetting.send("default_email_#{s}")) if has_attribute?("email_#{s}")
|
||||
end
|
||||
end
|
||||
|
||||
%w{new_topic_duration_minutes auto_track_topics_after_msecs}.each do |s|
|
||||
define_method("set_default_other_#{s}") do
|
||||
@ -1058,16 +1031,6 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
%w{external_links_in_new_tab enable_quoting dynamic_favicon disable_jump_reply edit_history_public}.each do |s|
|
||||
define_method("set_default_other_#{s}") do
|
||||
self.send("#{s}=", SiteSetting.send("default_other_#{s}")) if has_attribute?(s)
|
||||
end
|
||||
end
|
||||
|
||||
def set_default_topics_automatic_unpin
|
||||
self.automatically_unpin_topics = SiteSetting.default_topics_automatic_unpin
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
@ -1090,14 +1053,11 @@ end
|
||||
# last_seen_at :datetime
|
||||
# admin :boolean default(FALSE), not null
|
||||
# last_emailed_at :datetime
|
||||
# email_digests :boolean not null
|
||||
# trust_level :integer not null
|
||||
# email_private_messages :boolean default(TRUE)
|
||||
# email_direct :boolean default(TRUE), not null
|
||||
# approved :boolean default(FALSE), not null
|
||||
# approved_by_id :integer
|
||||
# approved_at :datetime
|
||||
# digest_after_days :integer
|
||||
# previous_visit_at :datetime
|
||||
# suspended_at :datetime
|
||||
# suspended_till :datetime
|
||||
@ -1107,24 +1067,16 @@ end
|
||||
# flag_level :integer default(0), not null
|
||||
# ip_address :inet
|
||||
# new_topic_duration_minutes :integer
|
||||
# external_links_in_new_tab :boolean not null
|
||||
# enable_quoting :boolean default(TRUE), not null
|
||||
# moderator :boolean default(FALSE)
|
||||
# blocked :boolean default(FALSE)
|
||||
# dynamic_favicon :boolean default(FALSE), not null
|
||||
# title :string(255)
|
||||
# uploaded_avatar_id :integer
|
||||
# email_always :boolean default(FALSE), not null
|
||||
# mailing_list_mode :boolean default(FALSE), not null
|
||||
# primary_group_id :integer
|
||||
# locale :string(10)
|
||||
# registration_ip_address :inet
|
||||
# last_redirected_to_top_at :datetime
|
||||
# disable_jump_reply :boolean default(FALSE), not null
|
||||
# edit_history_public :boolean default(FALSE), not null
|
||||
# trust_level_locked :boolean default(FALSE), not null
|
||||
# staged :boolean default(FALSE), not null
|
||||
# automatically_unpin_topics :boolean default(TRUE)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
@ -28,6 +28,10 @@ class UserEmailObserver < ActiveRecord::Observer
|
||||
enqueue :user_replied
|
||||
end
|
||||
|
||||
def linked
|
||||
enqueue :user_linked
|
||||
end
|
||||
|
||||
def private_message
|
||||
enqueue_private(:user_private_message)
|
||||
end
|
||||
@ -60,12 +64,12 @@ class UserEmailObserver < ActiveRecord::Observer
|
||||
EMAILABLE_POST_TYPES ||= Set.new [Post.types[:regular], Post.types[:whisper]]
|
||||
|
||||
def enqueue(type, delay=default_delay)
|
||||
return unless notification.user.email_direct?
|
||||
return unless notification.user.user_option.email_direct?
|
||||
perform_enqueue(type, delay)
|
||||
end
|
||||
|
||||
def enqueue_private(type, delay=private_delay)
|
||||
return unless notification.user.email_private_messages?
|
||||
return unless notification.user.user_option.email_private_messages?
|
||||
perform_enqueue(type, delay)
|
||||
end
|
||||
|
||||
|
29
app/models/user_option.rb
Normal file
29
app/models/user_option.rb
Normal file
@ -0,0 +1,29 @@
|
||||
class UserOption < ActiveRecord::Base
|
||||
self.primary_key = :user_id
|
||||
belongs_to :user
|
||||
before_create :set_defaults
|
||||
|
||||
def set_defaults
|
||||
self.email_always = SiteSetting.default_email_always
|
||||
self.mailing_list_mode = SiteSetting.default_email_mailing_list_mode
|
||||
self.email_direct = SiteSetting.default_email_direct
|
||||
self.automatically_unpin_topics = SiteSetting.default_topics_automatic_unpin
|
||||
self.email_private_messages = SiteSetting.default_email_private_messages
|
||||
|
||||
self.enable_quoting = SiteSetting.default_other_enable_quoting
|
||||
self.external_links_in_new_tab = SiteSetting.default_other_external_links_in_new_tab
|
||||
self.dynamic_favicon = SiteSetting.default_other_dynamic_favicon
|
||||
self.disable_jump_reply = SiteSetting.default_other_disable_jump_reply
|
||||
self.edit_history_public = SiteSetting.default_other_edit_history_public
|
||||
|
||||
|
||||
if SiteSetting.default_email_digest_frequency.to_i <= 0
|
||||
self.email_digests = false
|
||||
else
|
||||
self.email_digests = true
|
||||
self.digest_after_days ||= SiteSetting.default_email_digest_frequency.to_i
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
end
|
@ -31,7 +31,8 @@ class CurrentUserSerializer < BasicUserSerializer
|
||||
:is_anonymous,
|
||||
:post_queue_new_count,
|
||||
:show_queued_posts,
|
||||
:read_faq
|
||||
:read_faq,
|
||||
:automatically_unpin_topics
|
||||
|
||||
def include_site_flagged_posts_count?
|
||||
object.staff?
|
||||
@ -49,6 +50,26 @@ class CurrentUserSerializer < BasicUserSerializer
|
||||
object.user_stat.topic_reply_count
|
||||
end
|
||||
|
||||
def enable_quoting
|
||||
object.user_option.enable_quoting
|
||||
end
|
||||
|
||||
def disable_jump_reply
|
||||
object.user_option.disable_jump_reply
|
||||
end
|
||||
|
||||
def external_links_in_new_tab
|
||||
object.user_option.external_links_in_new_tab
|
||||
end
|
||||
|
||||
def dynamic_favicon
|
||||
object.user_option.dynamic_favicon
|
||||
end
|
||||
|
||||
def automatically_unpin_topics
|
||||
object.user_option.automatically_unpin_topics
|
||||
end
|
||||
|
||||
def site_flagged_posts_count
|
||||
PostAction.flagged_posts_count
|
||||
end
|
||||
|
20
app/serializers/user_option_serializer.rb
Normal file
20
app/serializers/user_option_serializer.rb
Normal file
@ -0,0 +1,20 @@
|
||||
class UserOptionSerializer < ApplicationSerializer
|
||||
attributes :user_id,
|
||||
:email_always,
|
||||
:mailing_list_mode,
|
||||
:email_digests,
|
||||
:email_private_messages,
|
||||
:email_direct,
|
||||
:external_links_in_new_tab,
|
||||
:dynamic_favicon,
|
||||
:enable_quoting,
|
||||
:disable_jump_reply,
|
||||
:digest_after_days,
|
||||
:automatically_unpin_topics,
|
||||
:edit_history_public
|
||||
|
||||
|
||||
def include_edit_history_public?
|
||||
!SiteSetting.edit_history_visible_to_public
|
||||
end
|
||||
end
|
@ -61,40 +61,33 @@ class UserSerializer < BasicUserSerializer
|
||||
:uploaded_avatar_id,
|
||||
:badge_count,
|
||||
:has_title_badges,
|
||||
:edit_history_public,
|
||||
:custom_fields,
|
||||
:user_fields,
|
||||
:topic_post_count,
|
||||
:pending_count,
|
||||
:profile_view_count,
|
||||
:automatically_unpin_topics
|
||||
:profile_view_count
|
||||
|
||||
has_one :invited_by, embed: :object, serializer: BasicUserSerializer
|
||||
has_many :groups, embed: :object, serializer: BasicGroupSerializer
|
||||
has_many :featured_user_badges, embed: :ids, serializer: UserBadgeSerializer, root: :user_badges
|
||||
has_one :card_badge, embed: :object, serializer: BadgeSerializer
|
||||
has_one :user_option, embed: :object, serializer: UserOptionSerializer
|
||||
|
||||
def include_user_option?
|
||||
can_edit
|
||||
end
|
||||
|
||||
staff_attributes :post_count,
|
||||
:can_be_deleted,
|
||||
:can_delete_all_posts
|
||||
|
||||
private_attributes :locale,
|
||||
:email_digests,
|
||||
:email_private_messages,
|
||||
:email_direct,
|
||||
:email_always,
|
||||
:digest_after_days,
|
||||
:mailing_list_mode,
|
||||
:auto_track_topics_after_msecs,
|
||||
:new_topic_duration_minutes,
|
||||
:external_links_in_new_tab,
|
||||
:dynamic_favicon,
|
||||
:enable_quoting,
|
||||
:muted_category_ids,
|
||||
:tracked_category_ids,
|
||||
:watched_category_ids,
|
||||
:private_messages_stats,
|
||||
:disable_jump_reply,
|
||||
:system_avatar_upload_id,
|
||||
:system_avatar_template,
|
||||
:gravatar_avatar_upload_id,
|
||||
@ -322,10 +315,6 @@ class UserSerializer < BasicUserSerializer
|
||||
object.badges.where(allow_title: true).count > 0
|
||||
end
|
||||
|
||||
def include_edit_history_public?
|
||||
can_edit && !SiteSetting.edit_history_visible_to_public
|
||||
end
|
||||
|
||||
def user_fields
|
||||
object.user_fields
|
||||
end
|
||||
|
@ -40,11 +40,14 @@ class AnonymousShadowCreator
|
||||
active: true,
|
||||
trust_level: 1,
|
||||
trust_level_locked: true,
|
||||
email_private_messages: false,
|
||||
email_digests: false,
|
||||
created_at: 1.day.ago # bypass new user restrictions
|
||||
)
|
||||
|
||||
shadow.user_option.update_columns(
|
||||
email_private_messages: false,
|
||||
email_digests: false
|
||||
)
|
||||
|
||||
shadow.email_tokens.update_all(confirmed: true)
|
||||
shadow.activate
|
||||
|
||||
|
@ -23,14 +23,17 @@ class UserAnonymizer
|
||||
@user.name = nil
|
||||
@user.date_of_birth = nil
|
||||
@user.title = nil
|
||||
@user.email_digests = false
|
||||
@user.email_private_messages = false
|
||||
@user.email_direct = false
|
||||
@user.email_always = false
|
||||
@user.mailing_list_mode = false
|
||||
@user.uploaded_avatar_id = nil
|
||||
@user.save
|
||||
|
||||
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.save
|
||||
|
||||
profile = @user.user_profile
|
||||
profile.destroy if profile
|
||||
@user.create_user_profile
|
||||
|
@ -6,18 +6,19 @@ class UserUpdater
|
||||
muted_category_ids: :muted
|
||||
}
|
||||
|
||||
USER_ATTR = [
|
||||
:email_digests,
|
||||
OPTION_ATTR = [
|
||||
:email_always,
|
||||
:mailing_list_mode,
|
||||
:email_digests,
|
||||
:email_direct,
|
||||
:email_private_messages,
|
||||
:external_links_in_new_tab,
|
||||
:enable_quoting,
|
||||
:dynamic_favicon,
|
||||
:mailing_list_mode,
|
||||
:disable_jump_reply,
|
||||
:edit_history_public,
|
||||
:automatically_unpin_topics,
|
||||
:digest_after_days
|
||||
]
|
||||
|
||||
def initialize(actor, user)
|
||||
@ -36,7 +37,6 @@ class UserUpdater
|
||||
|
||||
user.name = attributes.fetch(:name) { user.name }
|
||||
user.locale = attributes.fetch(:locale) { user.locale }
|
||||
user.digest_after_days = attributes.fetch(:digest_after_days) { user.digest_after_days }
|
||||
|
||||
if attributes[:auto_track_topics_after_msecs]
|
||||
user.auto_track_topics_after_msecs = attributes[:auto_track_topics_after_msecs].to_i
|
||||
@ -56,9 +56,19 @@ class UserUpdater
|
||||
end
|
||||
end
|
||||
|
||||
USER_ATTR.each do |attribute|
|
||||
|
||||
save_options = false
|
||||
OPTION_ATTR.each do |attribute|
|
||||
if attributes[attribute].present?
|
||||
user.send("#{attribute}=", attributes[attribute] == 'true')
|
||||
save_options = true
|
||||
|
||||
|
||||
if [true,false].include?(user.user_option.send(attribute))
|
||||
val = attributes[attribute].to_s == 'true'
|
||||
user.user_option.send("#{attribute}=", val)
|
||||
else
|
||||
user.user_option.send("#{attribute}=", attributes[attribute])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -72,7 +82,7 @@ class UserUpdater
|
||||
update_muted_users(attributes[:muted_usernames])
|
||||
end
|
||||
|
||||
user_profile.save && user.save
|
||||
(!save_options || user.user_option.save) && user_profile.save && user.save
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -2092,6 +2092,18 @@ en:
|
||||
---
|
||||
%{respond_instructions}
|
||||
|
||||
user_linked:
|
||||
subject_template: "[%{site_name}] %{topic_title}"
|
||||
text_body_template: |
|
||||
%{header_instructions}
|
||||
|
||||
%{message}
|
||||
|
||||
%{context}
|
||||
|
||||
---
|
||||
%{respond_instructions}
|
||||
|
||||
user_mentioned:
|
||||
subject_template: "[%{site_name}] %{topic_title}"
|
||||
text_body_template: |
|
||||
|
@ -16,14 +16,51 @@ User.seed do |u|
|
||||
u.active = true
|
||||
u.admin = true
|
||||
u.moderator = true
|
||||
u.email_direct = false
|
||||
u.approved = true
|
||||
u.email_private_messages = false
|
||||
u.trust_level = TrustLevel[4]
|
||||
end
|
||||
|
||||
UserOption.where(user_id: -1).update_all(
|
||||
email_private_messages: false,
|
||||
email_direct: false
|
||||
)
|
||||
|
||||
Group.user_trust_level_change!(-1, TrustLevel[4])
|
||||
|
||||
# 60 minutes after our migration runs we need to exectue this code...
|
||||
duration = Rails.env.production? ? 60 : 0
|
||||
if User.exec_sql("SELECT 1 FROM schema_migration_details
|
||||
WHERE EXISTS(
|
||||
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'users' AND column_name = 'enable_quoting'
|
||||
) AND
|
||||
name = 'AllowDefaultsOnUsersTable' AND
|
||||
created_at < (current_timestamp at time zone 'UTC' - interval '#{duration} minutes')
|
||||
").to_a.length > 0
|
||||
|
||||
|
||||
User.transaction do
|
||||
STDERR.puts "Removing superflous user columns!"
|
||||
%w[
|
||||
email_always
|
||||
mailing_list_mode
|
||||
email_digests
|
||||
email_direct
|
||||
email_private_messages
|
||||
external_links_in_new_tab
|
||||
enable_quoting
|
||||
dynamic_favicon
|
||||
disable_jump_reply
|
||||
edit_history_public
|
||||
automatically_unpin_topics
|
||||
digest_after_days
|
||||
].each do |column|
|
||||
User.exec_sql("ALTER TABLE users DROP column #{column}")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# User for the smoke tests
|
||||
if ENV["SMOKE"] == "1"
|
||||
smoke_user = User.seed do |u|
|
||||
@ -49,3 +86,4 @@ if ENV["SMOKE"] == "1"
|
||||
et.confirmed = true
|
||||
end
|
||||
end
|
||||
|
||||
|
30
db/migrate/20000225050318_add_schema_migration_details.rb
Normal file
30
db/migrate/20000225050318_add_schema_migration_details.rb
Normal file
@ -0,0 +1,30 @@
|
||||
class AddSchemaMigrationDetails < ActiveRecord::Migration
|
||||
def up
|
||||
# schema_migrations table is way too thin, does not give info about
|
||||
# duration of migration or the date it happened, this migration together with the
|
||||
# monkey patch adds a lot of information to the migration table
|
||||
|
||||
create_table :schema_migration_details do |t|
|
||||
t.string :version, null: false
|
||||
t.string :name
|
||||
t.string :hostname
|
||||
t.string :git_version
|
||||
t.string :rails_version
|
||||
t.integer :duration
|
||||
t.string :direction # this really should be a pg enum type but annoying to wire up for little gain
|
||||
t.datetime :created_at, null: false
|
||||
end
|
||||
|
||||
add_index :schema_migration_details, [:version]
|
||||
|
||||
execute("INSERT INTO schema_migration_details(version, created_at)
|
||||
SELECT version, current_timestamp
|
||||
FROM schema_migrations
|
||||
ORDER BY version
|
||||
")
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :schema_migration_details
|
||||
end
|
||||
end
|
76
db/migrate/20160225050317_add_user_options.rb
Normal file
76
db/migrate/20160225050317_add_user_options.rb
Normal file
@ -0,0 +1,76 @@
|
||||
class AddUserOptions < ActiveRecord::Migration
|
||||
def up
|
||||
|
||||
create_table :user_options, id: false do |t|
|
||||
t.integer :user_id, null: false
|
||||
t.boolean :email_always, null: false, default: false
|
||||
t.boolean :mailing_list_mode, null: false, default: false
|
||||
t.boolean :email_digests
|
||||
t.boolean :email_direct, null: false, default: true
|
||||
t.boolean :email_private_messages, null: false, default: true
|
||||
t.boolean :external_links_in_new_tab, null: false, default: false
|
||||
t.boolean :enable_quoting, null: false, default: true
|
||||
t.boolean :dynamic_favicon, null: false, default: false
|
||||
t.boolean :disable_jump_reply, null: false, default: false
|
||||
t.boolean :edit_history_public, null: false, default: false
|
||||
t.boolean :automatically_unpin_topics, null: false, default: true
|
||||
t.integer :digest_after_days
|
||||
end
|
||||
|
||||
add_index :user_options, [:user_id], unique: true
|
||||
|
||||
execute <<SQL
|
||||
INSERT INTO user_options (
|
||||
user_id,
|
||||
email_always,
|
||||
mailing_list_mode,
|
||||
email_digests,
|
||||
email_direct,
|
||||
email_private_messages,
|
||||
external_links_in_new_tab,
|
||||
enable_quoting,
|
||||
dynamic_favicon,
|
||||
disable_jump_reply,
|
||||
edit_history_public,
|
||||
automatically_unpin_topics,
|
||||
digest_after_days
|
||||
)
|
||||
SELECT id,
|
||||
email_always,
|
||||
mailing_list_mode,
|
||||
email_digests,
|
||||
email_direct,
|
||||
email_private_messages,
|
||||
external_links_in_new_tab,
|
||||
enable_quoting,
|
||||
dynamic_favicon,
|
||||
disable_jump_reply,
|
||||
edit_history_public,
|
||||
automatically_unpin_topics,
|
||||
digest_after_days
|
||||
FROM users
|
||||
SQL
|
||||
|
||||
# these can not be removed until a bit later
|
||||
# if we remove them now all currently running unicorns will start erroring out
|
||||
#
|
||||
# remove_column :users, :email_always
|
||||
# remove_column :users, :mailing_list_mode
|
||||
# remove_column :users, :email_digests
|
||||
# remove_column :users, :email_direct
|
||||
# remove_column :users, :email_private_messages
|
||||
# remove_column :users, :external_links_in_new_tab
|
||||
# remove_column :users, :enable_quoting
|
||||
# remove_column :users, :dynamic_favicon
|
||||
# remove_column :users, :disable_jump_reply
|
||||
# remove_column :users, :edit_history_public
|
||||
# remove_column :users, :automatically_unpin_topics
|
||||
# remove_column :users, :digest_after_days
|
||||
end
|
||||
|
||||
def down
|
||||
# we can not move backwards here cause columns
|
||||
# get removed an hour after the migration
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
10
db/migrate/20160225050318_allow_defaults_on_users_table.rb
Normal file
10
db/migrate/20160225050318_allow_defaults_on_users_table.rb
Normal file
@ -0,0 +1,10 @@
|
||||
class AllowDefaultsOnUsersTable < ActiveRecord::Migration
|
||||
def up
|
||||
# we need to temporarily change table a bit to ensure we can insert new records
|
||||
change_column :users, :email_digests, :boolean, null: false, default: true
|
||||
change_column :users, :external_links_in_new_tab, :boolean, null: false, default: false
|
||||
end
|
||||
|
||||
def down
|
||||
end
|
||||
end
|
54
lib/freedom_patches/schema_migration_details.rb
Normal file
54
lib/freedom_patches/schema_migration_details.rb
Normal file
@ -0,0 +1,54 @@
|
||||
module FreedomPatches
|
||||
module SchemaMigrationDetails
|
||||
def exec_migration(conn, direction)
|
||||
rval = nil
|
||||
|
||||
time = Benchmark.measure do
|
||||
rval=super
|
||||
end
|
||||
|
||||
sql = <<SQL
|
||||
INSERT INTO schema_migration_details(
|
||||
version,
|
||||
hostname,
|
||||
name,
|
||||
git_version,
|
||||
duration,
|
||||
direction,
|
||||
rails_version,
|
||||
created_at
|
||||
) values (
|
||||
:version,
|
||||
:hostname,
|
||||
:name,
|
||||
:git_version,
|
||||
:duration,
|
||||
:direction,
|
||||
:rails_version,
|
||||
:created_at
|
||||
)
|
||||
SQL
|
||||
|
||||
hostname = `hostname` rescue ""
|
||||
sql = ActiveRecord::Base.send(:sanitize_sql_array, [sql, {
|
||||
version: version || "",
|
||||
duration: (time.real * 1000).to_i,
|
||||
hostname: hostname,
|
||||
name: name,
|
||||
git_version: Discourse.git_version,
|
||||
created_at: Time.zone.now,
|
||||
direction: direction.to_s,
|
||||
rails_version: Rails.version
|
||||
}])
|
||||
|
||||
conn.execute(sql)
|
||||
|
||||
rval
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
class ActiveRecord::Migration
|
||||
prepend FreedomPatches::SchemaMigrationDetails
|
||||
end
|
@ -157,7 +157,7 @@ module PostGuardian
|
||||
return false unless post
|
||||
|
||||
if !post.hidden
|
||||
return true if post.wiki || SiteSetting.edit_history_visible_to_public || post.user.try(:edit_history_public)
|
||||
return true if post.wiki || SiteSetting.edit_history_visible_to_public || (post.user && post.user.user_option.edit_history_public)
|
||||
end
|
||||
|
||||
authenticated? &&
|
||||
|
@ -0,0 +1,32 @@
|
||||
require 'rails_helper'
|
||||
require_dependency "freedom_patches/schema_migration_details"
|
||||
|
||||
describe FreedomPatches::SchemaMigrationDetails do
|
||||
|
||||
# we usually don't really need this model so lets not clutter up with it
|
||||
class SchemaMigrationDetail < ActiveRecord::Base
|
||||
end
|
||||
|
||||
class TestMigration < ActiveRecord::Migration
|
||||
def up
|
||||
sleep 0.001
|
||||
end
|
||||
end
|
||||
|
||||
it "logs information on migration" do
|
||||
migration = TestMigration.new("awesome_migration","20160225050318")
|
||||
|
||||
ActiveRecord::Base.connection_pool.with_connection do |conn|
|
||||
migration.exec_migration(conn, :up)
|
||||
end
|
||||
|
||||
info = SchemaMigrationDetail.find_by(version: "20160225050318")
|
||||
|
||||
expect(info.duration).to be > 0
|
||||
expect(info.git_version).to eq Discourse.git_version
|
||||
expect(info.direction).to eq "up"
|
||||
expect(info.rails_version).to eq Rails.version
|
||||
expect(info.filename).to eq migration.filename
|
||||
expect(info.name).to eq "awesome_migration"
|
||||
end
|
||||
end
|
@ -510,7 +510,7 @@ describe Guardian do
|
||||
|
||||
it 'is true if the author has public edit history' do
|
||||
public_post_revision = Fabricate(:post_revision)
|
||||
public_post_revision.post.user.edit_history_public = true
|
||||
public_post_revision.post.user.user_option.edit_history_public = true
|
||||
expect(Guardian.new.can_see?(public_post_revision)).to be_truthy
|
||||
end
|
||||
end
|
||||
@ -533,7 +533,7 @@ describe Guardian do
|
||||
|
||||
it 'is true if the author has public edit history' do
|
||||
public_post_revision = Fabricate(:post_revision)
|
||||
public_post_revision.post.user.edit_history_public = true
|
||||
public_post_revision.post.user.user_option.edit_history_public = true
|
||||
expect(Guardian.new.can_see?(public_post_revision)).to be_truthy
|
||||
end
|
||||
end
|
||||
|
@ -21,7 +21,11 @@ describe EmailController do
|
||||
|
||||
context '.resubscribe' do
|
||||
|
||||
let(:user) { Fabricate(:user, email_digests: false) }
|
||||
let(:user) {
|
||||
user = Fabricate(:user)
|
||||
user.user_option.update_columns(email_digests: false)
|
||||
user
|
||||
}
|
||||
let(:key) { DigestUnsubscribeKey.create_key_for(user) }
|
||||
|
||||
context 'with a valid key' do
|
||||
@ -31,7 +35,7 @@ describe EmailController do
|
||||
end
|
||||
|
||||
it 'subscribes the user' do
|
||||
expect(user.email_digests).to eq(true)
|
||||
expect(user.user_option.email_digests).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
@ -39,7 +43,11 @@ describe EmailController do
|
||||
|
||||
context '.unsubscribe' do
|
||||
|
||||
let(:user) { Fabricate(:user, email_digests: true, email_direct: true, email_private_messages: true, email_always: true) }
|
||||
let(:user) {
|
||||
user = Fabricate(:user)
|
||||
user.user_option.update_columns(email_always: true, email_digests: true, email_direct: true, email_private_messages: true)
|
||||
user
|
||||
}
|
||||
let(:key) { DigestUnsubscribeKey.create_key_for(user) }
|
||||
|
||||
context 'from confirm unsubscribe email' do
|
||||
@ -49,10 +57,11 @@ describe EmailController do
|
||||
end
|
||||
|
||||
it 'unsubscribes from all emails' do
|
||||
expect(user.email_digests).to eq false
|
||||
expect(user.email_direct).to eq false
|
||||
expect(user.email_private_messages).to eq false
|
||||
expect(user.email_always).to eq false
|
||||
options = user.user_option
|
||||
expect(options.email_digests).to eq false
|
||||
expect(options.email_direct).to eq false
|
||||
expect(options.email_private_messages).to eq false
|
||||
expect(options.email_always).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
@ -63,7 +72,7 @@ describe EmailController do
|
||||
end
|
||||
|
||||
it 'unsubscribes the user' do
|
||||
expect(user.email_digests).to eq(false)
|
||||
expect(user.user_option.email_digests).to eq(false)
|
||||
end
|
||||
|
||||
it "sets the appropriate instance variables" do
|
||||
@ -90,7 +99,7 @@ describe EmailController do
|
||||
end
|
||||
|
||||
it 'does not unsubscribe the user' do
|
||||
expect(user.email_digests).to eq(true)
|
||||
expect(user.user_option.email_digests).to eq(true)
|
||||
end
|
||||
|
||||
it 'sets the appropriate instance variables' do
|
||||
@ -108,7 +117,7 @@ describe EmailController do
|
||||
end
|
||||
|
||||
it 'unsubscribes the user' do
|
||||
expect(user.email_digests).to eq(false)
|
||||
expect(user.user_option.email_digests).to eq(false)
|
||||
end
|
||||
|
||||
it 'sets the appropriate instance variables' do
|
||||
|
@ -55,7 +55,8 @@ describe Jobs::UserEmail do
|
||||
end
|
||||
|
||||
it "does send an email to a user that's been recently seen but has email_always set" do
|
||||
user.update_attributes(last_seen_at: 9.minutes.ago, email_always: true)
|
||||
user.update_attributes(last_seen_at: 9.minutes.ago)
|
||||
user.user_option.update_attributes(email_always: true)
|
||||
Email::Sender.any_instance.expects(:send)
|
||||
Jobs::UserEmail.new.execute(type: :user_replied, user_id: user.id, post_id: post.id)
|
||||
end
|
||||
@ -188,13 +189,13 @@ describe Jobs::UserEmail do
|
||||
it "does send the email if the notification has been seen but the user is set for email_always" do
|
||||
Email::Sender.any_instance.expects(:send)
|
||||
notification.update_column(:read, true)
|
||||
user.update_column(:email_always, true)
|
||||
user.user_option.update_column(:email_always, true)
|
||||
Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_id: notification.id)
|
||||
end
|
||||
|
||||
it "doesn't send the mail if the user is using mailing list mode" do
|
||||
Email::Sender.any_instance.expects(:send).never
|
||||
user.update_column(:mailing_list_mode, true)
|
||||
user.user_option.update_column(:mailing_list_mode, true)
|
||||
# sometimes, we pass the notification_id
|
||||
Jobs::UserEmail.new.execute(type: :user_mentioned, user_id: user.id, notification_id: notification.id, post_id: post.id)
|
||||
# other times, we only pass the type of notification
|
||||
|
@ -51,7 +51,7 @@ describe UserEmailObserver do
|
||||
include_examples "enqueue"
|
||||
|
||||
it "doesn't enqueue a job if the user has mention emails disabled" do
|
||||
notification.user.expects(:email_direct?).returns(false)
|
||||
notification.user.user_option.update_columns(email_direct: false)
|
||||
Jobs.expects(:enqueue_in).with(delay, :user_email, has_entry(type: type)).never
|
||||
UserEmailObserver.process_notification(notification)
|
||||
end
|
||||
@ -61,7 +61,7 @@ describe UserEmailObserver do
|
||||
include_examples "enqueue"
|
||||
|
||||
it "doesn't enqueue a job if the user has private message emails disabled" do
|
||||
notification.user.expects(:email_private_messages?).returns(false)
|
||||
notification.user.user_option.update_columns(email_private_messages: false)
|
||||
Jobs.expects(:enqueue_in).with(delay, :user_email, has_entry(type: type)).never
|
||||
UserEmailObserver.process_notification(notification)
|
||||
end
|
||||
@ -99,6 +99,14 @@ describe UserEmailObserver do
|
||||
include_examples "enqueue_public"
|
||||
end
|
||||
|
||||
context 'user_linked' do
|
||||
let(:type) { :user_linked }
|
||||
let(:delay) { SiteSetting.email_time_window_mins.minutes }
|
||||
let!(:notification) { create_notification(11) }
|
||||
|
||||
include_examples "enqueue_public"
|
||||
end
|
||||
|
||||
context 'user_posted' do
|
||||
let(:type) { :user_posted }
|
||||
let(:delay) { SiteSetting.email_time_window_mins.minutes }
|
||||
|
@ -152,15 +152,15 @@ describe User do
|
||||
it "is properly initialized" do
|
||||
expect(subject.approved_at).to be_blank
|
||||
expect(subject.approved_by_id).to be_blank
|
||||
expect(subject.email_private_messages).to eq(true)
|
||||
expect(subject.email_direct).to eq(true)
|
||||
end
|
||||
|
||||
context 'after_save' do
|
||||
before { subject.save }
|
||||
|
||||
it "has an email token" do
|
||||
it "has correct settings" do
|
||||
expect(subject.email_tokens).to be_present
|
||||
expect(subject.user_option.email_private_messages).to eq(true)
|
||||
expect(subject.user_option.email_direct).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
@ -1246,50 +1246,62 @@ describe User do
|
||||
context "when user preferences are overriden" do
|
||||
|
||||
before do
|
||||
SiteSetting.stubs(:default_email_digest_frequency).returns(1) # daily
|
||||
SiteSetting.stubs(:default_email_private_messages).returns(false)
|
||||
SiteSetting.stubs(:default_email_direct).returns(false)
|
||||
SiteSetting.stubs(:default_email_mailing_list_mode).returns(true)
|
||||
SiteSetting.stubs(:default_email_always).returns(true)
|
||||
SiteSetting.default_email_digest_frequency = 1 # daily
|
||||
SiteSetting.default_email_private_messages = false
|
||||
SiteSetting.default_email_direct = false
|
||||
SiteSetting.default_email_mailing_list_mode = true
|
||||
SiteSetting.default_email_always = true
|
||||
|
||||
SiteSetting.stubs(:default_other_new_topic_duration_minutes).returns(-1) # not viewed
|
||||
SiteSetting.stubs(:default_other_auto_track_topics_after_msecs).returns(0) # immediately
|
||||
SiteSetting.stubs(:default_other_external_links_in_new_tab).returns(true)
|
||||
SiteSetting.stubs(:default_other_enable_quoting).returns(false)
|
||||
SiteSetting.stubs(:default_other_dynamic_favicon).returns(true)
|
||||
SiteSetting.stubs(:default_other_disable_jump_reply).returns(true)
|
||||
SiteSetting.stubs(:default_other_edit_history_public).returns(true)
|
||||
SiteSetting.default_other_new_topic_duration_minutes = -1 # not viewed
|
||||
SiteSetting.default_other_auto_track_topics_after_msecs = 0 # immediately
|
||||
SiteSetting.default_other_external_links_in_new_tab = true
|
||||
SiteSetting.default_other_enable_quoting = false
|
||||
SiteSetting.default_other_dynamic_favicon = true
|
||||
SiteSetting.default_other_disable_jump_reply = true
|
||||
SiteSetting.default_other_edit_history_public = true
|
||||
|
||||
SiteSetting.stubs(:default_topics_automatic_unpin).returns(false)
|
||||
SiteSetting.default_topics_automatic_unpin = false
|
||||
|
||||
SiteSetting.stubs(:default_categories_watching).returns("1")
|
||||
SiteSetting.stubs(:default_categories_tracking).returns("2")
|
||||
SiteSetting.stubs(:default_categories_muted).returns("3")
|
||||
SiteSetting.default_categories_watching = "1"
|
||||
SiteSetting.default_categories_tracking = "2"
|
||||
SiteSetting.default_categories_muted = "3"
|
||||
end
|
||||
|
||||
it "has overriden preferences" do
|
||||
user = Fabricate(:user)
|
||||
|
||||
expect(user.digest_after_days).to eq(1)
|
||||
expect(user.email_private_messages).to eq(false)
|
||||
expect(user.email_direct).to eq(false)
|
||||
expect(user.mailing_list_mode).to eq(true)
|
||||
expect(user.email_always).to eq(true)
|
||||
options = user.user_option
|
||||
expect(options.email_always).to eq(true)
|
||||
expect(options.mailing_list_mode).to eq(true)
|
||||
expect(options.digest_after_days).to eq(1)
|
||||
expect(options.email_private_messages).to eq(false)
|
||||
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.edit_history_public).to eq(true)
|
||||
expect(options.automatically_unpin_topics).to eq(false)
|
||||
expect(options.email_direct).to eq(false)
|
||||
|
||||
expect(user.new_topic_duration_minutes).to eq(-1)
|
||||
expect(user.auto_track_topics_after_msecs).to eq(0)
|
||||
expect(user.external_links_in_new_tab).to eq(true)
|
||||
expect(user.enable_quoting).to eq(false)
|
||||
expect(user.dynamic_favicon).to eq(true)
|
||||
expect(user.disable_jump_reply).to eq(true)
|
||||
expect(user.edit_history_public).to eq(true)
|
||||
|
||||
expect(user.automatically_unpin_topics).to eq(false)
|
||||
|
||||
expect(CategoryUser.lookup(user, :watching).pluck(:category_id)).to eq([1])
|
||||
expect(CategoryUser.lookup(user, :tracking).pluck(:category_id)).to eq([2])
|
||||
expect(CategoryUser.lookup(user, :muted).pluck(:category_id)).to eq([3])
|
||||
end
|
||||
end
|
||||
|
||||
context UserOption 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)
|
||||
|
||||
user_id = user.id
|
||||
user.destroy!
|
||||
expect(UserOption.find_by(user_id: user_id)).to eq(nil)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
@ -15,6 +15,24 @@ describe UserSerializer do
|
||||
end
|
||||
end
|
||||
|
||||
context "as current user" do
|
||||
it "serializes options correctly" do
|
||||
# so we serialize more stuff
|
||||
SiteSetting.edit_history_visible_to_public = false
|
||||
|
||||
user = Fabricate.build(:user,
|
||||
user_profile: Fabricate.build(:user_profile),
|
||||
user_option: UserOption.new(edit_history_public: true),
|
||||
user_stat: UserStat.new
|
||||
)
|
||||
|
||||
json = UserSerializer.new(user, scope: Guardian.new(user), root: false).as_json
|
||||
|
||||
expect(json[:user_option][:edit_history_public]).to eq(true)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
context "with a user" do
|
||||
let(:user) { Fabricate.build(:user, user_profile: Fabricate.build(:user_profile) ) }
|
||||
let(:serializer) { UserSerializer.new(user, scope: Guardian.new, root: false) }
|
||||
@ -26,7 +44,7 @@ describe UserSerializer do
|
||||
|
||||
context "with `enable_names` true" do
|
||||
before do
|
||||
SiteSetting.stubs(:enable_names?).returns(true)
|
||||
SiteSetting.enable_names = true
|
||||
end
|
||||
|
||||
it "has a name" do
|
||||
@ -34,6 +52,7 @@ describe UserSerializer do
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
context "with `enable_names` false" do
|
||||
before do
|
||||
SiteSetting.stubs(:enable_names?).returns(false)
|
||||
|
@ -30,6 +30,9 @@ describe AnonymousShadowCreator do
|
||||
freeze_time 4.minutes.from_now
|
||||
shadow3 = AnonymousShadowCreator.get(user)
|
||||
|
||||
expect(shadow3.user_option.email_digests).to eq(false)
|
||||
expect(shadow3.user_option.email_private_messages).to eq(false)
|
||||
|
||||
expect(shadow2.id).not_to eq(shadow3.id)
|
||||
|
||||
end
|
||||
|
@ -19,13 +19,17 @@ describe UserAnonymizer do
|
||||
end
|
||||
|
||||
it "turns off all notifications" do
|
||||
user.user_option.update_columns(
|
||||
email_always: true
|
||||
)
|
||||
|
||||
make_anonymous
|
||||
user.reload
|
||||
expect(user.email_digests).to eq(false)
|
||||
expect(user.email_private_messages).to eq(false)
|
||||
expect(user.email_direct).to eq(false)
|
||||
expect(user.email_always).to eq(false)
|
||||
expect(user.mailing_list_mode).to eq(false)
|
||||
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.mailing_list_mode).to eq(false)
|
||||
end
|
||||
|
||||
it "resets profile to default values" do
|
||||
|
@ -32,26 +32,33 @@ describe UserUpdater do
|
||||
describe '#update' do
|
||||
it 'saves user' do
|
||||
user = Fabricate(:user, name: 'Billy Bob')
|
||||
updater = described_class.new(acting_user, user)
|
||||
updater = UserUpdater.new(acting_user, user)
|
||||
|
||||
updater.update(name: 'Jim Tom')
|
||||
|
||||
expect(user.reload.name).to eq 'Jim Tom'
|
||||
end
|
||||
|
||||
it 'updates bio' do
|
||||
it 'updates various fields' do
|
||||
user = Fabricate(:user)
|
||||
updater = described_class.new(acting_user, user)
|
||||
updater = UserUpdater.new(acting_user, user)
|
||||
|
||||
updater.update(bio_raw: 'my new bio')
|
||||
updater.update(bio_raw: 'my new bio',
|
||||
email_always: 'true',
|
||||
mailing_list_mode: true,
|
||||
digest_after_days: "8")
|
||||
user.reload
|
||||
|
||||
expect(user.reload.user_profile.bio_raw).to eq 'my new bio'
|
||||
expect(user.user_profile.bio_raw).to eq 'my new bio'
|
||||
expect(user.user_option.email_always).to eq true
|
||||
expect(user.user_option.mailing_list_mode).to eq true
|
||||
expect(user.user_option.digest_after_days).to eq 8
|
||||
end
|
||||
|
||||
context 'when update succeeds' do
|
||||
it 'returns true' do
|
||||
user = Fabricate(:user)
|
||||
updater = described_class.new(acting_user, user)
|
||||
updater = UserUpdater.new(acting_user, user)
|
||||
|
||||
expect(updater.update).to be_truthy
|
||||
end
|
||||
@ -61,7 +68,7 @@ describe UserUpdater do
|
||||
it 'returns false' do
|
||||
user = Fabricate(:user)
|
||||
user.stubs(save: false)
|
||||
updater = described_class.new(acting_user, user)
|
||||
updater = UserUpdater.new(acting_user, user)
|
||||
|
||||
expect(updater.update).to be_falsey
|
||||
end
|
||||
@ -73,7 +80,7 @@ describe UserUpdater do
|
||||
guardian = stub
|
||||
guardian.stubs(:can_grant_title?).with(user).returns(true)
|
||||
Guardian.stubs(:new).with(acting_user).returns(guardian)
|
||||
updater = described_class.new(acting_user, user)
|
||||
updater = UserUpdater.new(acting_user, user)
|
||||
|
||||
updater.update(title: 'Minion')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user