Revert "FEATURE: Site settings defaults per locale"
This reverts commit 468a8fcd20
.
This commit is contained in:
parent
4b53fe3cc7
commit
439fe8ba24
|
@ -64,16 +64,16 @@ export default Ember.Component.extend(BufferedContent, {
|
||||||
}.on("willDestroyElement"),
|
}.on("willDestroyElement"),
|
||||||
|
|
||||||
_save() {
|
_save() {
|
||||||
const setting = this.get('buffered'),
|
const self = this,
|
||||||
action = SiteSetting.update(setting.get('setting'), setting.get('value'));
|
setting = this.get('buffered');
|
||||||
action.then(() => {
|
SiteSetting.update(setting.get('setting'), setting.get('value')).then(function() {
|
||||||
this.set('validationMessage', null);
|
self.set('validationMessage', null);
|
||||||
this.commitBuffer();
|
self.commitBuffer();
|
||||||
}).catch((e) => {
|
}).catch(function(e) {
|
||||||
if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
|
if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
|
||||||
this.set('validationMessage', e.jqXHR.responseJSON.errors[0]);
|
self.set('validationMessage', e.jqXHR.responseJSON.errors[0]);
|
||||||
} else {
|
} else {
|
||||||
this.set('validationMessage', I18n.t('generic_error'));
|
self.set('validationMessage', I18n.t('generic_error'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -48,7 +48,7 @@ SiteSetting.reopenClass({
|
||||||
update(key, value) {
|
update(key, value) {
|
||||||
const data = {};
|
const data = {};
|
||||||
data[key] = value;
|
data[key] = value;
|
||||||
return ajax(`/admin/site_settings/${key}`, { type: 'PUT', data });
|
return ajax("/admin/site_settings/" + key, { type: 'PUT', data });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
class Admin::SiteSettingsController < Admin::AdminController
|
class Admin::SiteSettingsController < Admin::AdminController
|
||||||
rescue_from Discourse::InvalidParameters do |e|
|
|
||||||
render_json_error e.message, status: 422
|
|
||||||
end
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render_json_dump(site_settings: SiteSetting.all_settings, diags: SiteSetting.diags)
|
render_json_dump(site_settings: SiteSetting.all_settings, diags: SiteSetting.diags)
|
||||||
|
@ -12,17 +9,15 @@ class Admin::SiteSettingsController < Admin::AdminController
|
||||||
id = params[:id]
|
id = params[:id]
|
||||||
value = params[id]
|
value = params[id]
|
||||||
value.strip! if value.is_a?(String)
|
value.strip! if value.is_a?(String)
|
||||||
raise_access_hidden_setting(id)
|
begin
|
||||||
SiteSetting.set_and_log(id, value, current_user)
|
# note, as of Ruby 2.3 symbols are GC'd so this is considered safe
|
||||||
render nothing: true
|
if SiteSetting.hidden_settings.include?(id.to_sym)
|
||||||
end
|
raise Discourse::InvalidParameters, "You are not allowed to change hidden settings"
|
||||||
|
end
|
||||||
private
|
SiteSetting.set_and_log(id, value, current_user)
|
||||||
|
render nothing: true
|
||||||
def raise_access_hidden_setting(id)
|
rescue Discourse::InvalidParameters => e
|
||||||
# note, as of Ruby 2.3 symbols are GC'd so this is considered safe
|
render json: { errors: [e.message] }, status: 422
|
||||||
if SiteSetting.hidden_settings.include?(id.to_sym)
|
|
||||||
raise Discourse::InvalidParameters, "You are not allowed to change hidden settings"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,11 @@ class SiteSetting < ActiveRecord::Base
|
||||||
|
|
||||||
def self.load_settings(file)
|
def self.load_settings(file)
|
||||||
SiteSettings::YamlLoader.new(file).load do |category, name, default, opts|
|
SiteSettings::YamlLoader.new(file).load do |category, name, default, opts|
|
||||||
setting(name, default, opts.merge(category: category))
|
if opts.delete(:client)
|
||||||
|
client_setting(name, default, opts.merge(category: category))
|
||||||
|
else
|
||||||
|
setting(name, default, opts.merge(category: category))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -27,11 +31,6 @@ class SiteSetting < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# `current` hash is not populated everytime when load a site setting
|
|
||||||
# in order to support locale default. Instead, we simply `refresh!` once.
|
|
||||||
# This should only affects the spec in which you should populate `current`
|
|
||||||
refresh!
|
|
||||||
|
|
||||||
client_settings << :available_locales
|
client_settings << :available_locales
|
||||||
|
|
||||||
def self.available_locales
|
def self.available_locales
|
||||||
|
|
|
@ -59,9 +59,6 @@ Discourse::Application.configure do
|
||||||
end
|
end
|
||||||
|
|
||||||
config.after_initialize do
|
config.after_initialize do
|
||||||
SiteSetting.defaults.set_regardless_of_locale(:port, 3000)
|
|
||||||
SiteSetting.refresh!
|
|
||||||
|
|
||||||
if ENV['BULLET']
|
if ENV['BULLET']
|
||||||
Bullet.enable = true
|
Bullet.enable = true
|
||||||
Bullet.rails_logger = true
|
Bullet.rails_logger = true
|
||||||
|
|
|
@ -46,22 +46,4 @@ Discourse::Application.configure do
|
||||||
config.logger = Logger.new(nil)
|
config.logger = Logger.new(nil)
|
||||||
config.log_level = :fatal
|
config.log_level = :fatal
|
||||||
end
|
end
|
||||||
|
|
||||||
config.after_initialize do
|
|
||||||
SiteSetting.defaults.tap do |s|
|
|
||||||
s.set_regardless_of_locale(:s3_upload_bucket, 'bucket')
|
|
||||||
s.set_regardless_of_locale(:min_post_length, 5)
|
|
||||||
s.set_regardless_of_locale(:min_first_post_length, 5)
|
|
||||||
s.set_regardless_of_locale(:min_private_message_post_length, 10)
|
|
||||||
s.set_regardless_of_locale(:crawl_images, false)
|
|
||||||
s.set_regardless_of_locale(:download_remote_images_to_local, false)
|
|
||||||
s.set_regardless_of_locale(:unique_posts_mins, 0)
|
|
||||||
s.set_regardless_of_locale(:queue_jobs, false)
|
|
||||||
# disable plugins
|
|
||||||
if ENV['LOAD_PLUGINS'] == '1'
|
|
||||||
s.set_regardless_of_locale(:discourse_narrative_bot_enabled, false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
SiteSetting.refresh!
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,9 +12,6 @@
|
||||||
# shadowed_by_global - "Shadow" a site setting with a GlobalSetting. If the GlobalSetting
|
# shadowed_by_global - "Shadow" a site setting with a GlobalSetting. If the GlobalSetting
|
||||||
# exists it will be used instead of the setting and the setting will be hidden.
|
# exists it will be used instead of the setting and the setting will be hidden.
|
||||||
# Useful for things like API keys on multisite.
|
# Useful for things like API keys on multisite.
|
||||||
# locale_default - A hash which overrides according to `SiteSetting.default_locale`.
|
|
||||||
# The key should be as the same as possible value of default_locale.
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
# type: email - Must be a valid email address.
|
# type: email - Must be a valid email address.
|
||||||
# type: username - Must match the username of an existing user.
|
# type: username - Must match the username of an existing user.
|
||||||
|
@ -71,6 +68,11 @@ required:
|
||||||
default: ''
|
default: ''
|
||||||
|
|
||||||
basic:
|
basic:
|
||||||
|
default_locale:
|
||||||
|
default: 'en'
|
||||||
|
enum: 'LocaleSiteSetting'
|
||||||
|
refresh: true
|
||||||
|
shadowed_by_global: true
|
||||||
allow_user_locale:
|
allow_user_locale:
|
||||||
client: true
|
client: true
|
||||||
default: false
|
default: false
|
||||||
|
@ -430,24 +432,21 @@ posting:
|
||||||
min_post_length:
|
min_post_length:
|
||||||
client: true
|
client: true
|
||||||
min: 1
|
min: 1
|
||||||
default: 20
|
default:
|
||||||
locale_default:
|
test: 5
|
||||||
zh_CN: 8
|
default: 20
|
||||||
zh_TW: 8
|
|
||||||
min_first_post_length:
|
min_first_post_length:
|
||||||
client: true
|
client: true
|
||||||
min: 1
|
min: 1
|
||||||
default: 20
|
default:
|
||||||
locale_default:
|
test: 5
|
||||||
zh_CN: 8
|
default: 20
|
||||||
zh_TW: 8
|
|
||||||
min_private_message_post_length:
|
min_private_message_post_length:
|
||||||
client: true
|
client: true
|
||||||
min: 1
|
min: 1
|
||||||
default: 10
|
default:
|
||||||
locale_default:
|
test: 5
|
||||||
zh_CN: 3
|
default: 10
|
||||||
zh_TW: 3
|
|
||||||
max_post_length:
|
max_post_length:
|
||||||
client: true
|
client: true
|
||||||
default: 32000
|
default: 32000
|
||||||
|
@ -455,32 +454,17 @@ posting:
|
||||||
topic_featured_link_enabled:
|
topic_featured_link_enabled:
|
||||||
client: true
|
client: true
|
||||||
default: true
|
default: true
|
||||||
body_min_entropy:
|
body_min_entropy: 7
|
||||||
default: 7
|
|
||||||
locale_default:
|
|
||||||
zh_CN: 3
|
|
||||||
zh_TW: 3
|
|
||||||
min_topic_title_length:
|
min_topic_title_length:
|
||||||
client: true
|
client: true
|
||||||
default: 15
|
default: 15
|
||||||
locale_default:
|
|
||||||
zh_CN: 6
|
|
||||||
zh_TW: 6
|
|
||||||
max_topic_title_length:
|
max_topic_title_length:
|
||||||
client: true
|
client: true
|
||||||
default: 255
|
default: 255
|
||||||
max: 255
|
max: 255
|
||||||
title_min_entropy:
|
title_min_entropy: 10
|
||||||
default: 10
|
|
||||||
locale_default:
|
|
||||||
zh_CN: 3
|
|
||||||
zh_TW: 3
|
|
||||||
allow_uppercase_posts: false
|
allow_uppercase_posts: false
|
||||||
title_prettify:
|
title_prettify: true
|
||||||
default: true
|
|
||||||
locale_default:
|
|
||||||
zh_CN: false
|
|
||||||
zh_TW: false
|
|
||||||
title_fancy_entities: true
|
title_fancy_entities: true
|
||||||
min_private_message_title_length:
|
min_private_message_title_length:
|
||||||
client: true
|
client: true
|
||||||
|
@ -494,15 +478,9 @@ posting:
|
||||||
min_title_similar_length:
|
min_title_similar_length:
|
||||||
client: true
|
client: true
|
||||||
default: 10
|
default: 10
|
||||||
locale_default:
|
|
||||||
zh_CN: 4
|
|
||||||
zh_TW: 4
|
|
||||||
min_body_similar_length:
|
min_body_similar_length:
|
||||||
client: true
|
client: true
|
||||||
default: 15
|
default: 15
|
||||||
locale_default:
|
|
||||||
zh_CN: 5
|
|
||||||
zh_TW: 5
|
|
||||||
enable_private_messages:
|
enable_private_messages:
|
||||||
default: true
|
default: true
|
||||||
client: true
|
client: true
|
||||||
|
@ -546,11 +524,7 @@ posting:
|
||||||
newuser_max_attachments:
|
newuser_max_attachments:
|
||||||
client: true
|
client: true
|
||||||
default: 0
|
default: 0
|
||||||
post_excerpt_maxlength:
|
post_excerpt_maxlength: 300
|
||||||
default: 300
|
|
||||||
locale_default:
|
|
||||||
zh_CN: 120
|
|
||||||
zh_TW: 120
|
|
||||||
show_pinned_excerpt_mobile:
|
show_pinned_excerpt_mobile:
|
||||||
client: true
|
client: true
|
||||||
default: true
|
default: true
|
||||||
|
@ -629,11 +603,7 @@ email:
|
||||||
client: true
|
client: true
|
||||||
private_email_time_window_seconds: 20
|
private_email_time_window_seconds: 20
|
||||||
email_posts_context: 5
|
email_posts_context: 5
|
||||||
digest_min_excerpt_length:
|
digest_min_excerpt_length: 100
|
||||||
default: 100
|
|
||||||
locale_default:
|
|
||||||
zh_CN: 50
|
|
||||||
zh_TW: 50
|
|
||||||
digest_topics:
|
digest_topics:
|
||||||
default: 5
|
default: 5
|
||||||
min: 1
|
min: 1
|
||||||
|
@ -756,7 +726,9 @@ files:
|
||||||
refresh: true
|
refresh: true
|
||||||
type: list
|
type: list
|
||||||
crawl_images:
|
crawl_images:
|
||||||
default: true
|
default:
|
||||||
|
test: false
|
||||||
|
default: true
|
||||||
max_image_width:
|
max_image_width:
|
||||||
client: true
|
client: true
|
||||||
default: 690
|
default: 690
|
||||||
|
@ -764,7 +736,9 @@ files:
|
||||||
client: true
|
client: true
|
||||||
default: 500
|
default: 500
|
||||||
download_remote_images_to_local:
|
download_remote_images_to_local:
|
||||||
default: true
|
default:
|
||||||
|
test: false
|
||||||
|
default: true
|
||||||
download_remote_images_threshold: 10
|
download_remote_images_threshold: 10
|
||||||
download_remote_images_max_days_old:
|
download_remote_images_max_days_old:
|
||||||
default: 30
|
default: 30
|
||||||
|
@ -934,11 +908,7 @@ security:
|
||||||
|
|
||||||
onebox:
|
onebox:
|
||||||
enable_flash_video_onebox: false
|
enable_flash_video_onebox: false
|
||||||
post_onebox_maxlength:
|
post_onebox_maxlength: 500
|
||||||
default: 500
|
|
||||||
locale_default:
|
|
||||||
zh_CN: 200
|
|
||||||
zh_TW: 200
|
|
||||||
onebox_domains_blacklist:
|
onebox_domains_blacklist:
|
||||||
default: ''
|
default: ''
|
||||||
type: list
|
type: list
|
||||||
|
@ -984,7 +954,10 @@ spam:
|
||||||
auto_block_first_post_regex: ""
|
auto_block_first_post_regex: ""
|
||||||
|
|
||||||
rate_limits:
|
rate_limits:
|
||||||
unique_posts_mins: 5
|
unique_posts_mins:
|
||||||
|
default:
|
||||||
|
test: 0
|
||||||
|
default: 5
|
||||||
rate_limit_create_topic: 15
|
rate_limit_create_topic: 15
|
||||||
rate_limit_create_post: 5
|
rate_limit_create_post: 5
|
||||||
rate_limit_new_user_create_topic: 120
|
rate_limit_new_user_create_topic: 120
|
||||||
|
@ -1022,20 +995,28 @@ rate_limits:
|
||||||
|
|
||||||
developer:
|
developer:
|
||||||
force_hostname:
|
force_hostname:
|
||||||
hidden: true
|
hidden:
|
||||||
|
development: false
|
||||||
|
default: true
|
||||||
default: ''
|
default: ''
|
||||||
port:
|
port:
|
||||||
hidden: true
|
hidden:
|
||||||
default: ''
|
development: false
|
||||||
|
default: true
|
||||||
|
default:
|
||||||
|
development: 3000
|
||||||
|
default: ''
|
||||||
queue_jobs:
|
queue_jobs:
|
||||||
hidden: true
|
hidden:
|
||||||
default: true
|
development: false
|
||||||
|
default: true
|
||||||
|
default:
|
||||||
|
test: false
|
||||||
|
default: true
|
||||||
enable_long_polling:
|
enable_long_polling:
|
||||||
client: true
|
client: true
|
||||||
default: true
|
default: true
|
||||||
long_polling_interval:
|
long_polling_interval: 25000
|
||||||
default: 25000
|
|
||||||
max: 25000
|
|
||||||
long_polling_base_url:
|
long_polling_base_url:
|
||||||
client: true
|
client: true
|
||||||
default: '/'
|
default: '/'
|
||||||
|
@ -1163,19 +1144,12 @@ search:
|
||||||
min_search_term_length:
|
min_search_term_length:
|
||||||
client: true
|
client: true
|
||||||
default: 3
|
default: 3
|
||||||
locale_default:
|
|
||||||
zh_CN: 2
|
|
||||||
zh_TW: 2
|
|
||||||
|
|
||||||
search_tokenize_chinese_japanese_korean: false
|
search_tokenize_chinese_japanese_korean: false
|
||||||
search_prefer_recent_posts: false
|
search_prefer_recent_posts: false
|
||||||
search_recent_posts_size:
|
search_recent_posts_size: 100000
|
||||||
default: 100000
|
|
||||||
max: 100000
|
|
||||||
log_search_queries: true
|
log_search_queries: true
|
||||||
search_query_log_max_size:
|
search_query_log_max_size: 1000000
|
||||||
default: 1000000
|
|
||||||
max: 1000000
|
|
||||||
|
|
||||||
uncategorized:
|
uncategorized:
|
||||||
version_checks:
|
version_checks:
|
||||||
|
@ -1192,9 +1166,6 @@ uncategorized:
|
||||||
slug_generation_method:
|
slug_generation_method:
|
||||||
default: 'ascii'
|
default: 'ascii'
|
||||||
enum: 'SlugSetting'
|
enum: 'SlugSetting'
|
||||||
locale_default:
|
|
||||||
zh_CN: 'none'
|
|
||||||
zh_TW: 'none'
|
|
||||||
|
|
||||||
permalink_normalizations:
|
permalink_normalizations:
|
||||||
default: ''
|
default: ''
|
||||||
|
@ -1335,9 +1306,6 @@ uncategorized:
|
||||||
read_time_word_count:
|
read_time_word_count:
|
||||||
default: 500
|
default: 500
|
||||||
client: true
|
client: true
|
||||||
locale_default:
|
|
||||||
zh_CN: 350
|
|
||||||
zh_TW: 350
|
|
||||||
|
|
||||||
topic_page_title_includes_category: true
|
topic_page_title_includes_category: true
|
||||||
|
|
||||||
|
@ -1355,7 +1323,7 @@ user_preferences:
|
||||||
default_email_mailing_list_mode: false
|
default_email_mailing_list_mode: false
|
||||||
default_email_mailing_list_mode_frequency:
|
default_email_mailing_list_mode_frequency:
|
||||||
enum: 'MailingListModeSiteSetting'
|
enum: 'MailingListModeSiteSetting'
|
||||||
default: 1
|
default: 0
|
||||||
disable_mailing_list_mode:
|
disable_mailing_list_mode:
|
||||||
default: false
|
default: false
|
||||||
client: true
|
client: true
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
class CorrectDefaultEmailMailingListModeFrequency < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
execute "UPDATE site_settings SET value = '1' WHERE value = '0' AND name = 'default_email_mailing_list_mode_frequency';"
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -84,8 +84,6 @@ module Discourse
|
||||||
# Cross site request forgery
|
# Cross site request forgery
|
||||||
class CSRF < StandardError; end
|
class CSRF < StandardError; end
|
||||||
|
|
||||||
class Deprecation < StandardError; end
|
|
||||||
|
|
||||||
def self.filters
|
def self.filters
|
||||||
@filters ||= [:latest, :unread, :new, :read, :posted, :bookmarks]
|
@filters ||= [:latest, :unread, :new, :read, :posted, :bookmarks]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
require_dependency 'site_settings/deprecated_settings'
|
require_dependency 'enum'
|
||||||
require_dependency 'site_settings/type_supervisor'
|
|
||||||
require_dependency 'site_settings/defaults_provider'
|
|
||||||
require_dependency 'site_settings/db_provider'
|
require_dependency 'site_settings/db_provider'
|
||||||
|
require 'site_setting_validations'
|
||||||
|
|
||||||
module SiteSettingExtension
|
module SiteSettingExtension
|
||||||
include SiteSettings::DeprecatedSettings
|
include SiteSettingValidations
|
||||||
extend Forwardable
|
|
||||||
|
|
||||||
def_delegator :defaults, :site_locale, :default_locale
|
# For plugins, so they can tell if a feature is supported
|
||||||
def_delegator :defaults, :site_locale=, :default_locale=
|
def supported_types
|
||||||
def_delegator :defaults, :has_setting?
|
[:email, :username, :list, :enum]
|
||||||
def_delegators 'SiteSettings::TypeSupervisor', :types, :supported_types
|
end
|
||||||
|
|
||||||
# part 1 of refactor, centralizing the dependency here
|
# part 1 of refactor, centralizing the dependency here
|
||||||
def provider=(val)
|
def provider=(val)
|
||||||
|
@ -22,6 +20,22 @@ module SiteSettingExtension
|
||||||
@provider ||= SiteSettings::DbProvider.new(SiteSetting)
|
@provider ||= SiteSettings::DbProvider.new(SiteSetting)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def types
|
||||||
|
@types ||= Enum.new(string: 1,
|
||||||
|
time: 2,
|
||||||
|
integer: 3,
|
||||||
|
float: 4,
|
||||||
|
bool: 5,
|
||||||
|
null: 6,
|
||||||
|
enum: 7,
|
||||||
|
list: 8,
|
||||||
|
url_list: 9,
|
||||||
|
host_list: 10,
|
||||||
|
category_list: 11,
|
||||||
|
value_list: 12,
|
||||||
|
regex: 13)
|
||||||
|
end
|
||||||
|
|
||||||
def mutex
|
def mutex
|
||||||
@mutex ||= Mutex.new
|
@mutex ||= Mutex.new
|
||||||
end
|
end
|
||||||
|
@ -32,17 +46,25 @@ module SiteSettingExtension
|
||||||
end
|
end
|
||||||
|
|
||||||
def defaults
|
def defaults
|
||||||
@defaults ||= SiteSettings::DefaultsProvider.new(self)
|
@defaults ||= {}
|
||||||
end
|
|
||||||
|
|
||||||
def type_supervisor
|
|
||||||
@type_supervisor ||= SiteSettings::TypeSupervisor.new(defaults)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def categories
|
def categories
|
||||||
@categories ||= {}
|
@categories ||= {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def enums
|
||||||
|
@enums ||= {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def static_types
|
||||||
|
@static_types ||= {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def choices
|
||||||
|
@choices ||= {}
|
||||||
|
end
|
||||||
|
|
||||||
def shadowed_settings
|
def shadowed_settings
|
||||||
@shadowed_settings ||= []
|
@shadowed_settings ||= []
|
||||||
end
|
end
|
||||||
|
@ -63,14 +85,34 @@ module SiteSettingExtension
|
||||||
@previews ||= {}
|
@previews ||= {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validators
|
||||||
|
@validators ||= {}
|
||||||
|
end
|
||||||
|
|
||||||
def setting(name_arg, default = nil, opts = {})
|
def setting(name_arg, default = nil, opts = {})
|
||||||
name = name_arg.to_sym
|
name = name_arg.to_sym
|
||||||
mutex.synchronize do
|
mutex.synchronize do
|
||||||
defaults.load_setting(name,
|
self.defaults[name] = default
|
||||||
default,
|
|
||||||
opts.extract!(*SiteSettings::DefaultsProvider::CONSUMED_OPTS))
|
|
||||||
|
|
||||||
categories[name] = opts[:category] || :uncategorized
|
categories[name] = opts[:category] || :uncategorized
|
||||||
|
current_value = current.has_key?(name) ? current[name] : default
|
||||||
|
|
||||||
|
if enum = opts[:enum]
|
||||||
|
enums[name] = enum.is_a?(String) ? enum.constantize : enum
|
||||||
|
opts[:type] ||= :enum
|
||||||
|
end
|
||||||
|
|
||||||
|
if new_choices = opts[:choices]
|
||||||
|
|
||||||
|
new_choices = eval(new_choices) if new_choices.is_a?(String)
|
||||||
|
|
||||||
|
choices.has_key?(name) ?
|
||||||
|
choices[name].concat(new_choices) :
|
||||||
|
choices[name] = new_choices
|
||||||
|
end
|
||||||
|
|
||||||
|
if type = opts[:type]
|
||||||
|
static_types[name.to_sym] = type.to_sym
|
||||||
|
end
|
||||||
|
|
||||||
if opts[:hidden]
|
if opts[:hidden]
|
||||||
hidden_settings << name
|
hidden_settings << name
|
||||||
|
@ -82,6 +124,7 @@ module SiteSettingExtension
|
||||||
unless val.nil? || (val == ''.freeze)
|
unless val.nil? || (val == ''.freeze)
|
||||||
hidden_settings << name
|
hidden_settings << name
|
||||||
shadowed_settings << name
|
shadowed_settings << name
|
||||||
|
current_value = val
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -89,24 +132,31 @@ module SiteSettingExtension
|
||||||
refresh_settings << name
|
refresh_settings << name
|
||||||
end
|
end
|
||||||
|
|
||||||
if opts[:client]
|
|
||||||
client_settings << name.to_sym
|
|
||||||
end
|
|
||||||
|
|
||||||
if opts[:preview]
|
if opts[:preview]
|
||||||
previews[name] = opts[:preview]
|
previews[name] = opts[:preview]
|
||||||
end
|
end
|
||||||
|
|
||||||
type_supervisor.load_setting(name,
|
opts[:validator] = opts[:validator].try(:constantize)
|
||||||
opts.extract!(*SiteSettings::TypeSupervisor::CONSUMED_OPTS))
|
type = opts[:type] || get_data_type(name, defaults[name])
|
||||||
|
|
||||||
|
if validator_type = opts[:validator] || validator_for(type)
|
||||||
|
validators[name] = { class: validator_type, opts: opts }
|
||||||
|
end
|
||||||
|
|
||||||
|
current[name] = current_value
|
||||||
setup_methods(name)
|
setup_methods(name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# just like a setting, except that it is available in javascript via DiscourseSession
|
||||||
|
def client_setting(name, default = nil, opts = {})
|
||||||
|
setting(name, default, opts)
|
||||||
|
client_settings << name.to_sym
|
||||||
|
end
|
||||||
|
|
||||||
def settings_hash
|
def settings_hash
|
||||||
result = {}
|
result = {}
|
||||||
defaults.each_key do |s|
|
@defaults.each do |s, _|
|
||||||
result[s] = send(s).to_s
|
result[s] = send(s).to_s
|
||||||
end
|
end
|
||||||
result
|
result
|
||||||
|
@ -124,21 +174,32 @@ module SiteSettingExtension
|
||||||
|
|
||||||
# Retrieve all settings
|
# Retrieve all settings
|
||||||
def all_settings(include_hidden = false)
|
def all_settings(include_hidden = false)
|
||||||
defaults
|
@defaults
|
||||||
.reject { |s, _| !include_hidden && hidden_settings.include?(s) }
|
.reject { |s, _| hidden_settings.include?(s) && !include_hidden }
|
||||||
.map do |s, v|
|
.map do |s, v|
|
||||||
value = send(s)
|
value = send(s)
|
||||||
opts = {
|
type = types[get_data_type(s, value)]
|
||||||
setting: s,
|
opts = {
|
||||||
description: description(s),
|
setting: s,
|
||||||
default: defaults[s].to_s,
|
description: description(s),
|
||||||
value: value.to_s,
|
default: v.to_s,
|
||||||
category: categories[s],
|
type: type.to_s,
|
||||||
preview: previews[s]
|
value: value.to_s,
|
||||||
}.merge(type_supervisor.type_hash(s))
|
category: categories[s],
|
||||||
|
preview: previews[s]
|
||||||
|
}
|
||||||
|
|
||||||
opts
|
if type == :enum && enum_class(s)
|
||||||
end.unshift(defaults.locale_setting_hash)
|
opts.merge!(valid_values: enum_class(s).values, translate_names: enum_class(s).translate_names?)
|
||||||
|
elsif type == :enum
|
||||||
|
opts.merge!(valid_values: choices[s].map { |c| { name: c, value: c } }, translate_names: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
opts[:textarea] = true if static_types[s] == :textarea
|
||||||
|
|
||||||
|
opts[:choices] = choices[s] if choices.has_key? s
|
||||||
|
opts
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def description(setting)
|
def description(setting)
|
||||||
|
@ -156,22 +217,22 @@ module SiteSettingExtension
|
||||||
def refresh!
|
def refresh!
|
||||||
mutex.synchronize do
|
mutex.synchronize do
|
||||||
ensure_listen_for_changes
|
ensure_listen_for_changes
|
||||||
|
old = current
|
||||||
|
|
||||||
new_hash = Hash[*(defaults.db_all.map { |s|
|
new_hash = Hash[*(provider.all.map { |s|
|
||||||
[s.name.to_sym, type_supervisor.to_rb_value(s.name, s.value, s.data_type)]
|
[s.name.intern, convert(s.value, s.data_type, s.name)]
|
||||||
}.to_a.flatten)]
|
}.to_a.flatten)]
|
||||||
|
|
||||||
defaults_view = defaults.all
|
# add defaults, cause they are cached
|
||||||
|
new_hash = defaults.merge(new_hash)
|
||||||
# add locale default and defaults based on default_locale, cause they are cached
|
|
||||||
new_hash = defaults_view.merge(new_hash)
|
|
||||||
|
|
||||||
# add shadowed
|
# add shadowed
|
||||||
shadowed_settings.each { |ss| new_hash[ss] = GlobalSetting.send(ss) }
|
shadowed_settings.each { |ss| new_hash[ss] = GlobalSetting.send(ss) }
|
||||||
|
|
||||||
changes, deletions = diff_hash(new_hash, current)
|
changes, deletions = diff_hash(new_hash, old)
|
||||||
|
|
||||||
changes.each { |name, val| current[name] = val }
|
changes.each { |name, val| current[name] = val }
|
||||||
deletions.each { |name, _| current[name] = defaults_view[name] }
|
deletions.each { |name, val| current[name] = defaults[name] }
|
||||||
|
|
||||||
clear_cache!
|
clear_cache!
|
||||||
end
|
end
|
||||||
|
@ -221,9 +282,44 @@ module SiteSettingExtension
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_override!(name, val)
|
def add_override!(name, val)
|
||||||
val, type = type_supervisor.to_db_value(name, val)
|
type = get_data_type(name, defaults[name.to_sym])
|
||||||
|
|
||||||
|
val = val.to_s if type == types[:string]
|
||||||
|
|
||||||
|
if type == types[:bool] && val != true && val != false
|
||||||
|
val = (val == "t" || val == "true") ? 't' : 'f'
|
||||||
|
end
|
||||||
|
|
||||||
|
if type == types[:integer] && !val.is_a?(Integer)
|
||||||
|
val = val.to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
if type == types[:null] && val != ''
|
||||||
|
type = get_data_type(name, val)
|
||||||
|
end
|
||||||
|
|
||||||
|
if type == types[:enum]
|
||||||
|
val = val.to_i if defaults[name.to_sym].is_a?(Integer)
|
||||||
|
if enum_class(name)
|
||||||
|
raise Discourse::InvalidParameters.new(:value) unless enum_class(name).valid_value?(val)
|
||||||
|
else
|
||||||
|
raise Discourse::InvalidParameters.new(:value) unless choices[name].include?(val)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if v = validators[name]
|
||||||
|
validator = v[:class].new(v[:opts])
|
||||||
|
unless validator.valid_value?(val)
|
||||||
|
raise Discourse::InvalidParameters.new(validator.error_message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.respond_to? "validate_#{name}"
|
||||||
|
send("validate_#{name}", val)
|
||||||
|
end
|
||||||
|
|
||||||
provider.save(name, val, type)
|
provider.save(name, val, type)
|
||||||
current[name] = type_supervisor.to_rb_value(name, val)
|
current[name] = convert(val, type, name)
|
||||||
notify_clients!(name) if client_settings.include? name
|
notify_clients!(name) if client_settings.include? name
|
||||||
clear_cache!
|
clear_cache!
|
||||||
end
|
end
|
||||||
|
@ -236,10 +332,26 @@ module SiteSettingExtension
|
||||||
MessageBus.publish('/client_settings', name: name, value: self.send(name))
|
MessageBus.publish('/client_settings', name: name, value: self.send(name))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_setting?(name)
|
||||||
|
defaults.has_key?(name.to_sym) || defaults.has_key?("#{name}?".to_sym)
|
||||||
|
end
|
||||||
|
|
||||||
def requires_refresh?(name)
|
def requires_refresh?(name)
|
||||||
refresh_settings.include?(name.to_sym)
|
refresh_settings.include?(name.to_sym)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def is_valid_data?(name, value)
|
||||||
|
valid = true
|
||||||
|
type = get_data_type(name, defaults[name.to_sym])
|
||||||
|
|
||||||
|
if type == types[:integer]
|
||||||
|
# validate integer
|
||||||
|
valid = false unless value.to_i.is_a?(Integer)
|
||||||
|
end
|
||||||
|
|
||||||
|
valid
|
||||||
|
end
|
||||||
|
|
||||||
def filter_value(name, value)
|
def filter_value(name, value)
|
||||||
if %w[disabled_image_download_domains onebox_domains_blacklist exclude_rel_nofollow_domains email_domains_blacklist email_domains_whitelist white_listed_spam_host_domains].include? name
|
if %w[disabled_image_download_domains onebox_domains_blacklist exclude_rel_nofollow_domains email_domains_blacklist email_domains_whitelist white_listed_spam_host_domains].include? name
|
||||||
domain_array = []
|
domain_array = []
|
||||||
|
@ -250,7 +362,7 @@ module SiteSettingExtension
|
||||||
end
|
end
|
||||||
|
|
||||||
def set(name, value)
|
def set(name, value)
|
||||||
if has_setting?(name)
|
if has_setting?(name) && is_valid_data?(name, value)
|
||||||
value = filter_value(name, value)
|
value = filter_value(name, value)
|
||||||
self.send("#{name}=", value)
|
self.send("#{name}=", value)
|
||||||
Discourse.request_refresh! if requires_refresh?(name)
|
Discourse.request_refresh! if requires_refresh?(name)
|
||||||
|
@ -287,11 +399,90 @@ module SiteSettingExtension
|
||||||
[changes, deletions]
|
[changes, deletions]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_data_type(name, val)
|
||||||
|
return types[:null] if val.nil?
|
||||||
|
|
||||||
|
# Some types are just for validations like email.
|
||||||
|
# Only consider it valid if includes in `types`
|
||||||
|
if static_type = static_types[name.to_sym]
|
||||||
|
return types[static_type] if types.keys.include?(static_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
case val
|
||||||
|
when String
|
||||||
|
types[:string]
|
||||||
|
when Integer
|
||||||
|
types[:integer]
|
||||||
|
when Float
|
||||||
|
types[:float]
|
||||||
|
when TrueClass, FalseClass
|
||||||
|
types[:bool]
|
||||||
|
else
|
||||||
|
raise ArgumentError.new :val
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert(value, type, name)
|
||||||
|
case type
|
||||||
|
when types[:float]
|
||||||
|
value.to_f
|
||||||
|
when types[:integer]
|
||||||
|
value.to_i
|
||||||
|
when types[:bool]
|
||||||
|
value == true || value == "t" || value == "true"
|
||||||
|
when types[:null]
|
||||||
|
nil
|
||||||
|
when types[:enum]
|
||||||
|
defaults[name.to_sym].is_a?(Integer) ? value.to_i : value
|
||||||
|
else
|
||||||
|
return value if types[type]
|
||||||
|
# Otherwise it's a type error
|
||||||
|
raise ArgumentError.new :type
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def validator_for(type_name)
|
||||||
|
@validator_mapping ||= {
|
||||||
|
'email' => EmailSettingValidator,
|
||||||
|
'username' => UsernameSettingValidator,
|
||||||
|
types[:integer] => IntegerSettingValidator,
|
||||||
|
types[:string] => StringSettingValidator,
|
||||||
|
'list' => StringSettingValidator,
|
||||||
|
'enum' => StringSettingValidator,
|
||||||
|
'regex' => RegexSettingValidator
|
||||||
|
}
|
||||||
|
@validator_mapping[type_name]
|
||||||
|
end
|
||||||
|
|
||||||
|
DEPRECATED_SETTINGS = [
|
||||||
|
['use_https', 'force_https', '1.7']
|
||||||
|
]
|
||||||
|
|
||||||
|
def setup_deprecated_methods
|
||||||
|
DEPRECATED_SETTINGS.each do |old_setting, new_setting, version|
|
||||||
|
define_singleton_method old_setting do
|
||||||
|
logger.warn("`SiteSetting.#{old_setting}` has been deprecated and will be removed in the #{version} Release. Please use `SiteSetting.#{new_setting}` instead")
|
||||||
|
self.public_send new_setting
|
||||||
|
end
|
||||||
|
|
||||||
|
define_singleton_method "#{old_setting}?" do
|
||||||
|
logger.warn("`SiteSetting.#{old_setting}?` has been deprecated and will be removed in the #{version} Release. Please use `SiteSetting.#{new_setting}?` instead")
|
||||||
|
self.public_send "#{new_setting}?"
|
||||||
|
end
|
||||||
|
|
||||||
|
define_singleton_method "#{old_setting}=" do |val|
|
||||||
|
logger.warn("`SiteSetting.#{old_setting}=` has been deprecated and will be removed in the #{version} Release. Please use `SiteSetting.#{new_setting}=` instead")
|
||||||
|
self.public_send "#{new_setting}=", val
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def setup_methods(name)
|
def setup_methods(name)
|
||||||
clean_name = name.to_s.sub("?", "").to_sym
|
clean_name = name.to_s.sub("?", "").to_sym
|
||||||
|
|
||||||
define_singleton_method clean_name do
|
define_singleton_method clean_name do
|
||||||
if (c = @containers[provider.current_site])
|
c = @containers[provider.current_site]
|
||||||
|
if c
|
||||||
c[name]
|
c[name]
|
||||||
else
|
else
|
||||||
refresh!
|
refresh!
|
||||||
|
@ -308,6 +499,10 @@ module SiteSettingExtension
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def enum_class(name)
|
||||||
|
enums[name]
|
||||||
|
end
|
||||||
|
|
||||||
def get_hostname(url)
|
def get_hostname(url)
|
||||||
unless (URI.parse(url).scheme rescue nil).nil?
|
unless (URI.parse(url).scheme rescue nil).nil?
|
||||||
url = "http://#{url}" if URI.parse(url).scheme.nil?
|
url = "http://#{url}" if URI.parse(url).scheme.nil?
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
module SiteSettings; end
|
|
||||||
|
|
||||||
module SiteSettings::Validations
|
module SiteSettingValidations
|
||||||
|
|
||||||
def validate_error(key)
|
def validate_error(key)
|
||||||
raise Discourse::InvalidParameters.new(I18n.t("errors.site_settings.#{key}"))
|
raise Discourse::InvalidParameters.new(I18n.t("errors.site_settings.#{key}"))
|
||||||
end
|
end
|
|
@ -1,126 +0,0 @@
|
||||||
module SiteSettings; end
|
|
||||||
|
|
||||||
# A cache for providing default value based on site locale
|
|
||||||
class SiteSettings::DefaultsProvider
|
|
||||||
include Enumerable
|
|
||||||
|
|
||||||
CONSUMED_OPTS = %i[default locale_default].freeze
|
|
||||||
DEFAULT_LOCALE_KEY = :default_locale
|
|
||||||
DEFAULT_LOCALE = 'en'.freeze
|
|
||||||
DEFAULT_CATEGORY = 'required'.freeze
|
|
||||||
|
|
||||||
def initialize(site_setting)
|
|
||||||
@site_setting = site_setting
|
|
||||||
@site_setting.refresh_settings << DEFAULT_LOCALE_KEY
|
|
||||||
|
|
||||||
@cached = {}
|
|
||||||
@defaults = {}
|
|
||||||
@defaults[DEFAULT_LOCALE.to_sym] = {}
|
|
||||||
@site_locale = nil
|
|
||||||
refresh_site_locale!
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_setting(name_arg, value, opts = {})
|
|
||||||
name = name_arg.to_sym
|
|
||||||
@defaults[DEFAULT_LOCALE.to_sym][name] = value
|
|
||||||
|
|
||||||
if (locale_default = opts[:locale_default])
|
|
||||||
locale_default.each do |locale, v|
|
|
||||||
locale = locale.to_sym
|
|
||||||
@defaults[locale] ||= {}
|
|
||||||
@defaults[locale][name] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
refresh_cache!
|
|
||||||
end
|
|
||||||
|
|
||||||
def db_all
|
|
||||||
@site_setting.provider.all.delete_if { |s| s.name.to_sym == DEFAULT_LOCALE_KEY }
|
|
||||||
end
|
|
||||||
|
|
||||||
def all
|
|
||||||
@cached
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(name)
|
|
||||||
@cached[name.to_sym]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Used to override site settings in dev/test env
|
|
||||||
def set_regardless_of_locale(name, value)
|
|
||||||
name = name.to_sym
|
|
||||||
if @site_setting.has_setting?(name)
|
|
||||||
@defaults.each { |_, hash| hash.delete(name) }
|
|
||||||
@defaults[DEFAULT_LOCALE.to_sym][name] = value
|
|
||||||
value, type = @site_setting.type_supervisor.to_db_value(name, value)
|
|
||||||
@cached[name] = @site_setting.type_supervisor.to_rb_value(name, value, type)
|
|
||||||
else
|
|
||||||
raise ArgumentError.new("No setting named '#{name}' exists")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
alias [] get
|
|
||||||
|
|
||||||
attr_reader :site_locale
|
|
||||||
|
|
||||||
def site_locale=(val)
|
|
||||||
val = val.to_s
|
|
||||||
raise Discourse::InvalidParameters.new(:value) unless LocaleSiteSetting.valid_value?(val)
|
|
||||||
|
|
||||||
if val != @site_locale
|
|
||||||
@site_setting.provider.save(DEFAULT_LOCALE_KEY, val, SiteSetting.types[:string])
|
|
||||||
refresh_site_locale!
|
|
||||||
@site_setting.refresh!
|
|
||||||
Discourse.request_refresh!
|
|
||||||
end
|
|
||||||
|
|
||||||
@site_locale
|
|
||||||
end
|
|
||||||
|
|
||||||
def each
|
|
||||||
@cached.each { |k, v| yield k.to_sym, v }
|
|
||||||
end
|
|
||||||
|
|
||||||
def locale_setting_hash
|
|
||||||
{
|
|
||||||
setting: DEFAULT_LOCALE_KEY,
|
|
||||||
default: DEFAULT_LOCALE,
|
|
||||||
category: DEFAULT_CATEGORY,
|
|
||||||
description: @site_setting.description(DEFAULT_LOCALE_KEY),
|
|
||||||
type: SiteSetting.types[SiteSetting.types[:enum]],
|
|
||||||
preview: nil,
|
|
||||||
value: @site_locale,
|
|
||||||
valid_values: LocaleSiteSetting.values,
|
|
||||||
translate_names: LocaleSiteSetting.translate_names?
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def refresh_site_locale!
|
|
||||||
if GlobalSetting.respond_to?(DEFAULT_LOCALE_KEY) &&
|
|
||||||
(global_val = GlobalSetting.send(DEFAULT_LOCALE_KEY)) &&
|
|
||||||
!global_val.blank?
|
|
||||||
@site_locale = global_val
|
|
||||||
elsif (db_val = @site_setting.provider.find(DEFAULT_LOCALE_KEY))
|
|
||||||
@site_locale = db_val.value.to_s
|
|
||||||
else
|
|
||||||
@site_locale = DEFAULT_LOCALE
|
|
||||||
end
|
|
||||||
refresh_cache!
|
|
||||||
@site_locale
|
|
||||||
end
|
|
||||||
|
|
||||||
def has_setting?(name)
|
|
||||||
has_key?(name.to_sym) || has_key?("#{name.to_s}?".to_sym)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def has_key?(key)
|
|
||||||
@cached.key?(key) || key == DEFAULT_LOCALE_KEY
|
|
||||||
end
|
|
||||||
|
|
||||||
def refresh_cache!
|
|
||||||
@cached = @defaults[DEFAULT_LOCALE.to_sym].merge(@defaults.fetch(@site_locale.to_sym, {}))
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,26 +0,0 @@
|
||||||
module SiteSettings; end
|
|
||||||
|
|
||||||
module SiteSettings::DeprecatedSettings
|
|
||||||
DEPRECATED_SETTINGS = [
|
|
||||||
%w[use_https force_https 1.7]
|
|
||||||
]
|
|
||||||
|
|
||||||
def setup_deprecated_methods
|
|
||||||
DEPRECATED_SETTINGS.each do |old_setting, new_setting, version|
|
|
||||||
define_singleton_method old_setting do
|
|
||||||
logger.warn("`SiteSetting.#{old_setting}` has been deprecated and will be removed in the #{version} Release. Please use `SiteSetting.#{new_setting}` instead")
|
|
||||||
self.public_send new_setting
|
|
||||||
end
|
|
||||||
|
|
||||||
define_singleton_method "#{old_setting}?" do
|
|
||||||
logger.warn("`SiteSetting.#{old_setting}?` has been deprecated and will be removed in the #{version} Release. Please use `SiteSetting.#{new_setting}?` instead")
|
|
||||||
self.public_send "#{new_setting}?"
|
|
||||||
end
|
|
||||||
|
|
||||||
define_singleton_method "#{old_setting}=" do |val|
|
|
||||||
logger.warn("`SiteSetting.#{old_setting}=` has been deprecated and will be removed in the #{version} Release. Please use `SiteSetting.#{new_setting}=` instead")
|
|
||||||
self.public_send "#{new_setting}=", val
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -10,7 +10,7 @@ class SiteSettings::LocalProcessProvider
|
||||||
@settings[current_site] ||= {}
|
@settings[current_site] ||= {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize
|
def initialize()
|
||||||
@settings = {}
|
@settings = {}
|
||||||
self.current_site = "test"
|
self.current_site = "test"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,210 +0,0 @@
|
||||||
require_dependency 'site_settings/validations'
|
|
||||||
require_dependency 'enum'
|
|
||||||
|
|
||||||
module SiteSettings; end
|
|
||||||
|
|
||||||
class SiteSettings::TypeSupervisor
|
|
||||||
include SiteSettings::Validations
|
|
||||||
|
|
||||||
CONSUMED_OPTS = %i[enum choices type validator min max regex hidden regex_error].freeze
|
|
||||||
VALIDATOR_OPTS = %i[min max regex hidden regex_error].freeze
|
|
||||||
|
|
||||||
# For plugins, so they can tell if a feature is supported
|
|
||||||
SUPPORTED_TYPES = %i[email username list enum].freeze
|
|
||||||
|
|
||||||
def self.types
|
|
||||||
@types ||= Enum.new(string: 1,
|
|
||||||
time: 2,
|
|
||||||
integer: 3,
|
|
||||||
float: 4,
|
|
||||||
bool: 5,
|
|
||||||
null: 6,
|
|
||||||
enum: 7,
|
|
||||||
list: 8,
|
|
||||||
url_list: 9,
|
|
||||||
host_list: 10,
|
|
||||||
category_list: 11,
|
|
||||||
value_list: 12,
|
|
||||||
regex: 13,
|
|
||||||
email: 14,
|
|
||||||
username: 15)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.parse_value_type(val)
|
|
||||||
case val
|
|
||||||
when NilClass
|
|
||||||
self.types[:null]
|
|
||||||
when String
|
|
||||||
self.types[:string]
|
|
||||||
when Integer
|
|
||||||
self.types[:integer]
|
|
||||||
when Float
|
|
||||||
self.types[:float]
|
|
||||||
when TrueClass, FalseClass
|
|
||||||
self.types[:bool]
|
|
||||||
else
|
|
||||||
raise ArgumentError.new :val
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.supported_types
|
|
||||||
SUPPORTED_TYPES
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize(defaults_provider)
|
|
||||||
@defaults_provider = defaults_provider
|
|
||||||
@enums = {}
|
|
||||||
@static_types = {}
|
|
||||||
@choices = {}
|
|
||||||
@validators = {}
|
|
||||||
@types = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_setting(name_arg, opts = {})
|
|
||||||
name = name_arg.to_sym
|
|
||||||
|
|
||||||
if (enum = opts[:enum])
|
|
||||||
@enums[name] = enum.is_a?(String) ? enum.constantize : enum
|
|
||||||
opts[:type] ||= :enum
|
|
||||||
end
|
|
||||||
|
|
||||||
if (new_choices = opts[:choices])
|
|
||||||
new_choices = eval(new_choices) if new_choices.is_a?(String)
|
|
||||||
|
|
||||||
if @choices.has_key?(name)
|
|
||||||
@choices[name].concat(new_choices)
|
|
||||||
else
|
|
||||||
@choices[name] = new_choices
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if (type = opts[:type])
|
|
||||||
@static_types[name] = type.to_sym
|
|
||||||
end
|
|
||||||
@types[name] = get_data_type(name, @defaults_provider[name])
|
|
||||||
|
|
||||||
opts[:validator] = opts[:validator].try(:constantize)
|
|
||||||
if (validator_type = (opts[:validator] || validator_for(@types[name])))
|
|
||||||
@validators[name] = { class: validator_type, opts: opts.slice(*VALIDATOR_OPTS) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_rb_value(name, value, override_type = nil)
|
|
||||||
name = name.to_sym
|
|
||||||
type = @types[name] = (override_type || @types[name] || get_data_type(name, value))
|
|
||||||
|
|
||||||
case type
|
|
||||||
when self.class.types[:float]
|
|
||||||
value.to_f
|
|
||||||
when self.class.types[:integer]
|
|
||||||
value.to_i
|
|
||||||
when self.class.types[:bool]
|
|
||||||
value == true || value == 't' || value == 'true'
|
|
||||||
when self.class.types[:null]
|
|
||||||
nil
|
|
||||||
when self.class.types[:enum]
|
|
||||||
@defaults_provider[name].is_a?(Integer) ? value.to_i : value.to_s
|
|
||||||
when self.class.types[:string]
|
|
||||||
value.to_s
|
|
||||||
else
|
|
||||||
return value if self.class.types[type]
|
|
||||||
# Otherwise it's a type error
|
|
||||||
raise ArgumentError.new :type
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_db_value(name, value)
|
|
||||||
val, type = normalize_input(name, value)
|
|
||||||
validate_value(name, type, val)
|
|
||||||
[val, type]
|
|
||||||
end
|
|
||||||
|
|
||||||
def type_hash(name)
|
|
||||||
name = name.to_sym
|
|
||||||
type = self.class.types[@types[name]]
|
|
||||||
|
|
||||||
result = { type: type.to_s }
|
|
||||||
|
|
||||||
if type == :enum
|
|
||||||
if (klass = enum_class(name))
|
|
||||||
result.merge!(valid_values: klass.values, translate_names: klass.translate_names?)
|
|
||||||
else
|
|
||||||
result.merge!(valid_values: @choices[name].map { |c| { name: c, value: c } }, translate_names: false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
result[:choices] = @choices[name] if @choices.has_key? name
|
|
||||||
result
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def normalize_input(name, val)
|
|
||||||
name = name.to_sym
|
|
||||||
type = @types[name] || self.class.parse_value_type(val)
|
|
||||||
|
|
||||||
if type == self.class.types[:bool]
|
|
||||||
val = (val == true || val == 't' || val == 'true') ? 't' : 'f'
|
|
||||||
elsif type == self.class.types[:integer] && !val.is_a?(Integer)
|
|
||||||
val = val.to_i
|
|
||||||
elsif type == self.class.types[:null] && val != ''
|
|
||||||
type = get_data_type(name, val)
|
|
||||||
elsif type == self.class.types[:enum]
|
|
||||||
val = @defaults_provider[name].is_a?(Integer) ? val.to_i : val.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
[val, type]
|
|
||||||
end
|
|
||||||
|
|
||||||
def validate_value(name, type, val)
|
|
||||||
if type == self.class.types[:enum]
|
|
||||||
if enum_class(name)
|
|
||||||
raise Discourse::InvalidParameters.new(:value) unless enum_class(name).valid_value?(val)
|
|
||||||
else
|
|
||||||
raise Discourse::InvalidParameters.new(:value) unless @choices[name].include?(val)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if (v = @validators[name])
|
|
||||||
validator = v[:class].new(v[:opts])
|
|
||||||
unless validator.valid_value?(val)
|
|
||||||
raise Discourse::InvalidParameters, "#{name.to_s}: #{validator.error_message}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
validate_method = "validate_#{name}"
|
|
||||||
if self.respond_to? validate_method
|
|
||||||
send(validate_method, val)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_data_type(name, val)
|
|
||||||
# Some types are just for validations like email.
|
|
||||||
# Only consider it valid if includes in `types`
|
|
||||||
if (static_type = @static_types[name.to_sym])
|
|
||||||
return self.class.types[static_type] if self.class.types.keys.include?(static_type)
|
|
||||||
end
|
|
||||||
|
|
||||||
self.class.parse_value_type(val)
|
|
||||||
end
|
|
||||||
|
|
||||||
def enum_class(name)
|
|
||||||
@enums[name]
|
|
||||||
end
|
|
||||||
|
|
||||||
def validator_for(type_name)
|
|
||||||
case type_name
|
|
||||||
when self.class.types[:email]
|
|
||||||
EmailSettingValidator
|
|
||||||
when self.class.types[:username]
|
|
||||||
UsernameSettingValidator
|
|
||||||
when self.class.types[:integer]
|
|
||||||
IntegerSettingValidator
|
|
||||||
when self.class.types[:regex]
|
|
||||||
RegexSettingValidator
|
|
||||||
when self.class.types[:string], self.class.types[:list], self.class.types[:enum]
|
|
||||||
StringSettingValidator
|
|
||||||
else nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,26 +1,32 @@
|
||||||
module SiteSettings; end
|
module SiteSettings; end
|
||||||
|
|
||||||
class SiteSettings::YamlLoader
|
class SiteSettings::YamlLoader
|
||||||
|
|
||||||
def initialize(file)
|
def initialize(file)
|
||||||
@file = file
|
@file = file
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def env_val(value)
|
||||||
|
if value.is_a?(Hash)
|
||||||
|
value.has_key?(Rails.env) ? value[Rails.env] : value['default']
|
||||||
|
else
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def load
|
def load
|
||||||
yaml = YAML.load_file(@file)
|
yaml = YAML.load_file(@file)
|
||||||
yaml.each_key do |category|
|
yaml.each_key do |category|
|
||||||
yaml[category].each do |setting_name, hash|
|
yaml[category].each do |setting_name, hash|
|
||||||
if hash.is_a?(Hash)
|
if hash.is_a?(Hash)
|
||||||
# Get default value for the site setting:
|
# Get default value for the site setting:
|
||||||
value = hash.delete('default')
|
value = env_val(hash.delete('default'))
|
||||||
if value.is_a?(Hash)
|
|
||||||
raise Discourse::Deprecation, "Site setting per env is no longer supported. Error setting: #{setting_name}"
|
if hash.key?('hidden')
|
||||||
|
hash['hidden'] = env_val(hash.delete('hidden'))
|
||||||
end
|
end
|
||||||
|
|
||||||
if hash['hidden']&.is_a?(Hash)
|
yield category, setting_name, value, hash.symbolize_keys!
|
||||||
raise Discourse::Deprecation, "Hidden site setting per env is no longer supported. Error setting: #{setting_name}"
|
|
||||||
end
|
|
||||||
|
|
||||||
yield category, setting_name, value, hash.deep_symbolize_keys!
|
|
||||||
else
|
else
|
||||||
# Simplest case. site_setting_name: 'default value'
|
# Simplest case. site_setting_name: 'default value'
|
||||||
yield category, setting_name, hash, {}
|
yield category, setting_name, hash, {}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
plugins:
|
plugins:
|
||||||
discourse_narrative_bot_enabled:
|
discourse_narrative_bot_enabled:
|
||||||
default: true
|
default:
|
||||||
|
default: true
|
||||||
|
test: false
|
||||||
client: true
|
client: true
|
||||||
disable_discourse_narrative_bot_welcome_post:
|
disable_discourse_narrative_bot_welcome_post:
|
||||||
default: false
|
default: false
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
require 'benchmark/ips'
|
|
||||||
require File.expand_path('../../../../config/environment', __FILE__)
|
|
||||||
|
|
||||||
# Put pre conditions here
|
|
||||||
# Used db but it's OK in the most cases
|
|
||||||
|
|
||||||
# build the cache
|
|
||||||
SiteSetting.title = SecureRandom.hex
|
|
||||||
SiteSetting.default_locale = SiteSetting.default_locale == 'en' ? 'zh_CN' : 'en'
|
|
||||||
SiteSetting.refresh!
|
|
||||||
|
|
||||||
tests = [
|
|
||||||
["current cache", lambda do
|
|
||||||
SiteSetting.title
|
|
||||||
SiteSetting.enable_sso
|
|
||||||
end
|
|
||||||
],
|
|
||||||
["change default locale with current cache refreshed", lambda do
|
|
||||||
SiteSetting.default_locale = SiteSetting.default_locale == 'en' ? 'zh_CN' : 'en'
|
|
||||||
end
|
|
||||||
],
|
|
||||||
["change site setting", lambda do
|
|
||||||
SiteSetting.title = SecureRandom.hex
|
|
||||||
end
|
|
||||||
],
|
|
||||||
]
|
|
||||||
|
|
||||||
Benchmark.ips do |x|
|
|
||||||
tests.each do |test, proc|
|
|
||||||
x.report(test, proc)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# 2017-08-02 - Erick's Site Setting change
|
|
||||||
|
|
||||||
# Before
|
|
||||||
# Calculating -------------------------------------
|
|
||||||
# current cache 167.518k (±12.1%) i/s - 822.983k in 5.000478s
|
|
||||||
# change default locale with current cache refreshed
|
|
||||||
# 174.173 (±16.7%) i/s - 845.000 in 5.015281s
|
|
||||||
# change site setting 132.956 (±16.5%) i/s - 663.000 in 5.124766s
|
|
||||||
|
|
||||||
# After
|
|
||||||
# Calculating -------------------------------------
|
|
||||||
# current cache 167.170k (±12.2%) i/s - 824.688k in 5.022784s
|
|
||||||
# change default locale with current cache refreshed
|
|
||||||
# 79.876 (±16.3%) i/s - 392.000 in 5.067448s
|
|
||||||
# change site setting 129.085 (±13.2%) i/s - 636.000 in 5.032536s
|
|
|
@ -1,32 +0,0 @@
|
||||||
require 'ruby-prof'
|
|
||||||
|
|
||||||
def profile(&blk)
|
|
||||||
result = RubyProf.profile(&blk)
|
|
||||||
printer = RubyProf::GraphHtmlPrinter.new(result)
|
|
||||||
printer.print(STDOUT)
|
|
||||||
end
|
|
||||||
profile { '' } # loading profiler dependency
|
|
||||||
|
|
||||||
require File.expand_path('../../../../config/environment', __FILE__)
|
|
||||||
|
|
||||||
# warming up
|
|
||||||
SiteSetting.title
|
|
||||||
SiteSetting.enable_sso
|
|
||||||
SiteSetting.default_locale = SiteSetting.default_locale == 'en' ? 'zh_CN' : 'en'
|
|
||||||
SiteSetting.title = SecureRandom.hex
|
|
||||||
|
|
||||||
profile do
|
|
||||||
SiteSetting.title
|
|
||||||
end
|
|
||||||
|
|
||||||
profile do
|
|
||||||
SiteSetting.enable_sso
|
|
||||||
end
|
|
||||||
|
|
||||||
profile do
|
|
||||||
SiteSetting.default_locale = SiteSetting.default_locale == 'en' ? 'zh_CN' : 'en'
|
|
||||||
end
|
|
||||||
|
|
||||||
profile do
|
|
||||||
SiteSetting.title = SecureRandom.hex
|
|
||||||
end
|
|
|
@ -64,7 +64,7 @@ describe SiteSettingExtension do
|
||||||
expect(settings.hello).to eq(99)
|
expect(settings.hello).to eq(99)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "publishes changes cross sites" do
|
it "Publishes changes cross sites" do
|
||||||
settings.setting(:hello, 1)
|
settings.setting(:hello, 1)
|
||||||
settings2.setting(:hello, 1)
|
settings2.setting(:hello, 1)
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ describe SiteSettingExtension do
|
||||||
|
|
||||||
it "should publish changes to clients" do
|
it "should publish changes to clients" do
|
||||||
settings.setting("test_setting", 100)
|
settings.setting("test_setting", 100)
|
||||||
settings.setting("test_setting", nil, client: true)
|
settings.client_setting("test_setting")
|
||||||
|
|
||||||
messages = MessageBus.track_publish do
|
messages = MessageBus.track_publish do
|
||||||
settings.test_setting = 88
|
settings.test_setting = 88
|
||||||
|
@ -155,11 +155,8 @@ describe SiteSettingExtension do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "remove_override" do
|
describe "remove_override" do
|
||||||
before do
|
|
||||||
settings.setting(:test_override, "test")
|
|
||||||
settings.refresh!
|
|
||||||
end
|
|
||||||
it "correctly nukes overrides" do
|
it "correctly nukes overrides" do
|
||||||
|
settings.setting(:test_override, "test")
|
||||||
settings.test_override = "bla"
|
settings.test_override = "bla"
|
||||||
settings.remove_override!(:test_override)
|
settings.remove_override!(:test_override)
|
||||||
expect(settings.test_override).to eq("test")
|
expect(settings.test_override).to eq("test")
|
||||||
|
@ -266,7 +263,6 @@ describe SiteSettingExtension do
|
||||||
settings.setting(:test_int_enum, 1, enum: TestIntEnumClass)
|
settings.setting(:test_int_enum, 1, enum: TestIntEnumClass)
|
||||||
settings.test_int_enum = "2"
|
settings.test_int_enum = "2"
|
||||||
settings.refresh!
|
settings.refresh!
|
||||||
expect(settings.defaults[:test_int_enum]).to eq(1)
|
|
||||||
expect(settings.test_int_enum).to eq(2)
|
expect(settings.test_int_enum).to eq(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -276,7 +272,7 @@ describe SiteSettingExtension do
|
||||||
|
|
||||||
class TestEnumClass
|
class TestEnumClass
|
||||||
def self.valid_value?(v)
|
def self.valid_value?(v)
|
||||||
self.values.include?(v)
|
true
|
||||||
end
|
end
|
||||||
def self.values
|
def self.values
|
||||||
['en']
|
['en']
|
||||||
|
@ -303,10 +299,6 @@ describe SiteSettingExtension do
|
||||||
expect(settings.all_settings.detect { |s| s[:setting] == :test_enum }).to be_present
|
expect(settings.all_settings.detect { |s| s[:setting] == :test_enum }).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should report error when being set other values' do
|
|
||||||
expect { settings.test_enum = 'not_in_enum' }.to raise_error(Discourse::InvalidParameters)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when overridden' do
|
context 'when overridden' do
|
||||||
after :each do
|
after :each do
|
||||||
settings.remove_override!(:validated_setting)
|
settings.remove_override!(:validated_setting)
|
||||||
|
@ -392,14 +384,6 @@ describe SiteSettingExtension do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".set_and_log" do
|
|
||||||
it "raises an error when set for an invalid setting name" do
|
|
||||||
expect {
|
|
||||||
settings.set_and_log("provider", "haxxed")
|
|
||||||
}.to raise_error(ArgumentError)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "filter domain name" do
|
describe "filter domain name" do
|
||||||
before do
|
before do
|
||||||
settings.setting(:white_listed_spam_host_domains, "www.example.com")
|
settings.setting(:white_listed_spam_host_domains, "www.example.com")
|
||||||
|
@ -519,62 +503,4 @@ describe SiteSettingExtension do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'locale default overrides are respected' do
|
|
||||||
before do
|
|
||||||
settings.setting(:test_override, 'default', locale_default: { zh_CN: 'cn' })
|
|
||||||
settings.refresh!
|
|
||||||
end
|
|
||||||
|
|
||||||
after do
|
|
||||||
settings.remove_override!(:test_override)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'ensures the default cache expired after overriding the default_locale' do
|
|
||||||
expect(settings.test_override).to eq('default')
|
|
||||||
settings.default_locale = 'zh_CN'
|
|
||||||
expect(settings.test_override).to eq('cn')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the saved setting even locale default exists' do
|
|
||||||
expect(settings.test_override).to eq('default')
|
|
||||||
settings.default_locale = 'zh_CN'
|
|
||||||
settings.test_override = 'saved'
|
|
||||||
expect(settings.test_override).to eq('saved')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.requires_refresh?' do
|
|
||||||
it 'always refresh default_locale always require refresh' do
|
|
||||||
expect(settings.requires_refresh?(:default_locale)).to be_truthy
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.default_locale' do
|
|
||||||
it 'is always loaded' do
|
|
||||||
expect(settings.default_locale).to eq 'en'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.default_locale=' do
|
|
||||||
it 'can be changed' do
|
|
||||||
settings.default_locale = 'zh_CN'
|
|
||||||
expect(settings.default_locale).to eq 'zh_CN'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'refresh!' do
|
|
||||||
settings.expects(:refresh!)
|
|
||||||
settings.default_locale = 'zh_CN'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'expires the cache' do
|
|
||||||
settings.default_locale = 'zh_CN'
|
|
||||||
expect(Rails.cache.exist?(SiteSettingExtension.client_settings_cache_key)).to be_falsey
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'refreshes the client' do
|
|
||||||
Discourse.expects(:request_refresh!)
|
|
||||||
settings.default_locale = 'zh_CN'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,268 +0,0 @@
|
||||||
require 'rails_helper'
|
|
||||||
require_dependency 'site_settings/defaults_provider'
|
|
||||||
|
|
||||||
describe SiteSettings::DefaultsProvider do
|
|
||||||
|
|
||||||
let :provider_local do
|
|
||||||
SiteSettings::LocalProcessProvider.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def new_settings(provider)
|
|
||||||
Class.new do
|
|
||||||
extend SiteSettingExtension
|
|
||||||
self.provider = provider
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
let :settings do
|
|
||||||
new_settings(provider_local)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'inserts default_locale into refresh' do
|
|
||||||
it 'when initialize' do
|
|
||||||
expect(settings.refresh_settings.include?(SiteSettings::DefaultsProvider::DEFAULT_LOCALE_KEY)).to be_truthy
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.db_all' do
|
|
||||||
it 'collects values from db except default locale' do
|
|
||||||
settings.provider.save(SiteSettings::DefaultsProvider::DEFAULT_LOCALE_KEY,
|
|
||||||
'en',
|
|
||||||
SiteSetting.types[:string])
|
|
||||||
expect(settings.defaults.db_all).to eq([])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'can collect values from db' do
|
|
||||||
settings.provider.save('try_a', 1, SiteSetting.types[:integer])
|
|
||||||
settings.provider.save('try_b', 2, SiteSetting.types[:integer])
|
|
||||||
expect(settings.defaults.db_all.count).to eq 2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'expose default cache according to locale' do
|
|
||||||
before(:each) do
|
|
||||||
settings.setting(:test_override, 'default', locale_default: { zh_CN: 'cn' })
|
|
||||||
settings.setting(:test_default, 'test', regex: '^\S+$')
|
|
||||||
settings.refresh!
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.all' do
|
|
||||||
it 'returns all values according to the current locale' do
|
|
||||||
expect(settings.defaults.all).to eq(test_override: 'default', test_default: 'test')
|
|
||||||
settings.defaults.site_locale = 'zh_CN'
|
|
||||||
settings.defaults.refresh_site_locale!
|
|
||||||
expect(settings.defaults.all).to eq(test_override: 'cn', test_default: 'test')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.get' do
|
|
||||||
it 'returns the default value to a site setting' do
|
|
||||||
expect(settings.defaults.get(:test_override)).to eq 'default'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'accepts a string as the parameters' do
|
|
||||||
expect(settings.defaults.get('test_override')).to eq 'default'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the default value according to current locale' do
|
|
||||||
expect(settings.defaults.get(:test_override)).to eq 'default'
|
|
||||||
settings.defaults.site_locale = 'zh_CN'
|
|
||||||
expect(settings.defaults.get(:test_override)).to eq 'cn'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.set_regardless_of_locale' do
|
|
||||||
let(:val) { 'env_overriden' }
|
|
||||||
|
|
||||||
it 'sets the default value to a site setting regardless the locale' do
|
|
||||||
settings.defaults.set_regardless_of_locale(:test_override, val)
|
|
||||||
expect(settings.defaults.get(:test_override)).to eq val
|
|
||||||
settings.defaults.site_locale = 'zh_CN'
|
|
||||||
expect(settings.defaults.get(:test_override)).to eq val
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'handles the string' do
|
|
||||||
settings.defaults.set_regardless_of_locale('test_override', val)
|
|
||||||
expect(settings.defaults.get(:test_override)).to eq val
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'converts the data type' do
|
|
||||||
settings.defaults.set_regardless_of_locale(:test_override, 1)
|
|
||||||
expect(settings.defaults.get(:test_override)).to eq '1'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'raises when the setting does not exists' do
|
|
||||||
expect {
|
|
||||||
settings.defaults.set_regardless_of_locale(:not_exist, 1)
|
|
||||||
}.to raise_error(ArgumentError)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'raises when the value is not valid' do
|
|
||||||
expect {
|
|
||||||
settings.defaults.set_regardless_of_locale(:test_default, 'regex will fail')
|
|
||||||
}.to raise_error(Discourse::InvalidParameters)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.each' do
|
|
||||||
it 'yields the pair of site settings' do
|
|
||||||
expect { |b| settings.defaults.each(&b) }.to yield_successive_args([:test_override, 'default'], [:test_default, 'test'])
|
|
||||||
settings.defaults.site_locale = 'zh_CN'
|
|
||||||
expect { |b| settings.defaults.each(&b) }.to yield_successive_args([:test_override, 'cn'], [:test_default, 'test'])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.site_locale' do
|
|
||||||
it 'returns the current site locale' do
|
|
||||||
expect(settings.defaults.site_locale).to eq 'en'
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when locale is set in the db' do
|
|
||||||
let(:db_val) { 'zr' }
|
|
||||||
let(:global_val) { 'gr' }
|
|
||||||
|
|
||||||
before do
|
|
||||||
settings.provider.save(SiteSettings::DefaultsProvider::DEFAULT_LOCALE_KEY,
|
|
||||||
db_val,
|
|
||||||
SiteSetting.types[:string])
|
|
||||||
settings.defaults.refresh_site_locale!
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should load from database' do
|
|
||||||
expect(settings.defaults.site_locale).to eq db_val
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'prioritizes GlobalSetting than value from db' do
|
|
||||||
GlobalSetting.stubs(:default_locale).returns(global_val)
|
|
||||||
settings.defaults.refresh_site_locale!
|
|
||||||
expect(settings.defaults.site_locale).to eq global_val
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'ignores blank GlobalSetting' do
|
|
||||||
GlobalSetting.stubs(:default_locale).returns('')
|
|
||||||
settings.defaults.refresh_site_locale!
|
|
||||||
expect(settings.defaults.site_locale).to eq db_val
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.site_locale=' do
|
|
||||||
it 'changes and store the current site locale' do
|
|
||||||
settings.defaults.site_locale = 'zh_CN'
|
|
||||||
expect(settings.defaults.site_locale).to eq 'zh_CN'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'changes and store the current site locale' do
|
|
||||||
expect { settings.defaults.site_locale = 'random' }.to raise_error(Discourse::InvalidParameters)
|
|
||||||
expect(settings.defaults.site_locale).to eq 'en'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "don't change when it's shadowed" do
|
|
||||||
GlobalSetting.stubs(:default_locale).returns('shadowed')
|
|
||||||
settings.defaults.site_locale = 'zh_CN'
|
|
||||||
expect(settings.defaults.site_locale).to eq 'shadowed'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'refresh_site_locale! when called' do
|
|
||||||
settings.defaults.expects(:refresh_site_locale!)
|
|
||||||
settings.defaults.site_locale = 'zh_CN'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'refreshes the client when changed' do
|
|
||||||
Discourse.expects(:request_refresh!).once
|
|
||||||
settings.defaults.site_locale = 'zh_CN'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "doesn't refresh the client when changed" do
|
|
||||||
Discourse.expects(:request_refresh!).never
|
|
||||||
settings.defaults.site_locale = 'en'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.locale_setting_hash' do
|
|
||||||
it 'returns the hash for client display' do
|
|
||||||
result = settings.defaults.locale_setting_hash
|
|
||||||
|
|
||||||
expect(result[:setting]).to eq(SiteSettings::DefaultsProvider::DEFAULT_LOCALE_KEY)
|
|
||||||
expect(result[:default]).to eq(SiteSettings::DefaultsProvider::DEFAULT_LOCALE)
|
|
||||||
expect(result[:type]).to eq(SiteSetting.types[SiteSetting.types[:enum]])
|
|
||||||
expect(result[:preview]).to be_nil
|
|
||||||
expect(result[:value]).to eq(SiteSettings::DefaultsProvider::DEFAULT_LOCALE)
|
|
||||||
expect(result[:category]).to eq(SiteSettings::DefaultsProvider::DEFAULT_CATEGORY)
|
|
||||||
expect(result[:valid_values]).to eq(LocaleSiteSetting.values)
|
|
||||||
expect(result[:translate_names]).to eq(LocaleSiteSetting.translate_names?)
|
|
||||||
expect(result[:description]).not_to be_nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.load_setting' do
|
|
||||||
it 'adds a setting to the cache' do
|
|
||||||
settings.defaults.load_setting('new_a', 1)
|
|
||||||
expect(settings.defaults[:new_a]).to eq 1
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'takes care of locale default' do
|
|
||||||
settings.defaults.load_setting(:new_b, 1, locale_default: { zh_CN: 2, zh_TW: 2 })
|
|
||||||
expect(settings.defaults[:new_b]).to eq 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.refresh_site_locale!' do
|
|
||||||
it 'loads the change to locale' do
|
|
||||||
expect(settings.defaults.site_locale).to eq 'en'
|
|
||||||
settings.provider.save(SiteSettings::DefaultsProvider::DEFAULT_LOCALE_KEY,
|
|
||||||
'zh_CN',
|
|
||||||
SiteSetting.types[:string])
|
|
||||||
settings.defaults.refresh_site_locale!
|
|
||||||
expect(settings.defaults.site_locale).to eq 'zh_CN'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'loads from GlobalSettings' do
|
|
||||||
expect(settings.defaults.site_locale).to eq 'en'
|
|
||||||
GlobalSetting.stubs(:default_locale).returns('fr')
|
|
||||||
settings.defaults.refresh_site_locale!
|
|
||||||
expect(settings.defaults.site_locale).to eq 'fr'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'prioritized GlobalSettings than db' do
|
|
||||||
expect(settings.defaults.site_locale).to eq 'en'
|
|
||||||
settings.provider.save(SiteSettings::DefaultsProvider::DEFAULT_LOCALE_KEY,
|
|
||||||
'zh_CN',
|
|
||||||
SiteSetting.types[:string])
|
|
||||||
GlobalSetting.stubs(:default_locale).returns('fr')
|
|
||||||
settings.defaults.refresh_site_locale!
|
|
||||||
expect(settings.defaults.site_locale).to eq 'fr'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.has_setting?' do
|
|
||||||
before do
|
|
||||||
settings.setting(:r, 1)
|
|
||||||
settings.setting(:question?, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "returns true when it's present in the cache" do
|
|
||||||
expect(settings.defaults.has_setting?(:r)).to be_truthy
|
|
||||||
end
|
|
||||||
|
|
||||||
it '"responds when the arg is string' do
|
|
||||||
expect(settings.defaults.has_setting?('r')).to be_truthy
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'default_locale always exists' do
|
|
||||||
expect(settings.defaults.has_setting?(SiteSettings::DefaultsProvider::DEFAULT_LOCALE_KEY)).to be_truthy
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns false when the key is not exist' do
|
|
||||||
expect(settings.defaults.has_setting?('no_key')).to be_falsey
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'checks name with question mark' do
|
|
||||||
expect(settings.defaults.has_setting?(:question)).to be_truthy
|
|
||||||
expect(settings.defaults.has_setting?('question')).to be_truthy
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,341 +0,0 @@
|
||||||
require 'rails_helper'
|
|
||||||
require_dependency 'site_settings/type_supervisor'
|
|
||||||
|
|
||||||
describe SiteSettings::TypeSupervisor do
|
|
||||||
let :provider_local do
|
|
||||||
SiteSettings::LocalProcessProvider.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def new_settings(provider)
|
|
||||||
Class.new do
|
|
||||||
extend SiteSettingExtension
|
|
||||||
self.provider = provider
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
let :settings do
|
|
||||||
new_settings(provider_local)
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { SiteSettings::TypeSupervisor }
|
|
||||||
|
|
||||||
describe 'constants' do
|
|
||||||
it 'validator opts are the subset of consumed opts' do
|
|
||||||
expect(Set.new(SiteSettings::TypeSupervisor::CONSUMED_OPTS).superset?(
|
|
||||||
Set.new(SiteSettings::TypeSupervisor::VALIDATOR_OPTS))).to be_truthy
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#types' do
|
|
||||||
context "verify enum sequence" do
|
|
||||||
it "'string' should be at 1st position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:string]).to eq(1)
|
|
||||||
end
|
|
||||||
it "'time' should be at 2nd position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:time]).to eq(2)
|
|
||||||
end
|
|
||||||
it "'integer' should be at 3rd position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:integer]).to eq(3)
|
|
||||||
end
|
|
||||||
it "'float' should be at 4th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:float]).to eq(4)
|
|
||||||
end
|
|
||||||
it "'bool' should be at 5th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:bool]).to eq(5)
|
|
||||||
end
|
|
||||||
it "'null' should be at 6th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:null]).to eq(6)
|
|
||||||
end
|
|
||||||
it "'enum' should be at 7th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:enum]).to eq(7)
|
|
||||||
end
|
|
||||||
it "'list' should be at 8th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:list]).to eq(8)
|
|
||||||
end
|
|
||||||
it "'url_list' should be at 9th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:url_list]).to eq(9)
|
|
||||||
end
|
|
||||||
it "'host_list' should be at 10th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:host_list]).to eq(10)
|
|
||||||
end
|
|
||||||
it "'category_list' should be at 11th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:category_list]).to eq(11)
|
|
||||||
end
|
|
||||||
it "'value_list' should be at 12th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:value_list]).to eq(12)
|
|
||||||
end
|
|
||||||
it "'regex' should be at 13th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:regex]).to eq(13)
|
|
||||||
end
|
|
||||||
it "'email' should be at 14th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:email]).to eq(14)
|
|
||||||
end
|
|
||||||
it "'username' should be at 15th position" do
|
|
||||||
expect(SiteSettings::TypeSupervisor.types[:username]).to eq(15)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#parse_value_type' do
|
|
||||||
it 'returns :null type when the value is nil' do
|
|
||||||
expect(subject.parse_value_type(nil)).to eq(SiteSetting.types[:null])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns :integer type when the value is int' do
|
|
||||||
expect(subject.parse_value_type(2)).to eq(SiteSetting.types[:integer])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns :integer type when the value is large int' do
|
|
||||||
expect(subject.parse_value_type(99999999999999999999999999999999999)).to eq(SiteSetting.types[:integer])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns :float type when the value is float' do
|
|
||||||
expect(subject.parse_value_type(1.23)).to eq(SiteSetting.types[:float])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns :bool type when the value is true' do
|
|
||||||
expect(subject.parse_value_type(true)).to eq(SiteSetting.types[:bool])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns :bool type when the value is false' do
|
|
||||||
expect(subject.parse_value_type(false)).to eq(SiteSetting.types[:bool])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'raises when the value is not listed' do
|
|
||||||
expect {
|
|
||||||
subject.parse_value_type(Object.new)
|
|
||||||
}.to raise_error ArgumentError
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with different data types' do
|
|
||||||
class TestEnumClass
|
|
||||||
def self.valid_value?(v)
|
|
||||||
self.values.include?(v)
|
|
||||||
end
|
|
||||||
def self.values
|
|
||||||
['en']
|
|
||||||
end
|
|
||||||
def self.translate_names?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class TestSmallThanTenValidator
|
|
||||||
def initialize(opts)
|
|
||||||
end
|
|
||||||
def valid_value?(v)
|
|
||||||
v < 10
|
|
||||||
end
|
|
||||||
def error_message
|
|
||||||
''
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
before do
|
|
||||||
settings.setting(:type_null, nil)
|
|
||||||
settings.setting(:type_int, 1)
|
|
||||||
settings.setting(:type_true, true)
|
|
||||||
settings.setting(:type_false, false)
|
|
||||||
settings.setting(:type_float, 2.3232)
|
|
||||||
settings.setting(:type_string, 'string')
|
|
||||||
settings.setting(:type_enum_default_string, '2', type: 'enum', choices: ['2'])
|
|
||||||
settings.setting(:type_enum_class, 'en', enum: 'TestEnumClass')
|
|
||||||
settings.setting(:type_validator, 5, validator: 'TestSmallThanTenValidator')
|
|
||||||
settings.setting(:type_mock_validate_method, 'no_value')
|
|
||||||
settings.setting(:type_custom, 'custom', type: 'list')
|
|
||||||
settings.refresh!
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.to_db_value' do
|
|
||||||
let(:true_val) { 't' }
|
|
||||||
let(:false_val) { 'f' }
|
|
||||||
|
|
||||||
it 'returns nil value' do
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_null, nil)).to eq [nil, SiteSetting.types[:null]]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'gives a second chance to guess even told :null type' do
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_null, 1)).to eq [1, SiteSetting.types[:integer]]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'writes `t` or `f` given the possible bool value' do
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_true, true)).to eq [true_val, SiteSetting.types[:bool]]
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_true, 't')).to eq [true_val, SiteSetting.types[:bool]]
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_true, 'true')).to eq [true_val, SiteSetting.types[:bool]]
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_true, false)).to eq [false_val, SiteSetting.types[:bool]]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'writes `f` if given not `true` value' do
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_true, '')).to eq [false_val, SiteSetting.types[:bool]]
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_true, nil)).to eq [false_val, SiteSetting.types[:bool]]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns floats value' do
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_float, 1.2)).to eq [1.2, SiteSetting.types[:float]]
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_float, 1)).to eq [1.0, SiteSetting.types[:float]]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns string value' do
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_string, 'a')).to eq ['a', SiteSetting.types[:string]]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns enum value with string default' do
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_enum_default_string, 2)).to eq ['2', SiteSetting.types[:enum]]
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_enum_default_string, '2')).to eq ['2', SiteSetting.types[:enum]]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'raises when it does not in the enum choices' do
|
|
||||||
expect {
|
|
||||||
settings.type_supervisor.to_db_value(:type_enum_default_string, 'random')
|
|
||||||
}.to raise_error Discourse::InvalidParameters
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns enum value for the given enum class' do
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_enum_class, 'en')).to eq ['en', SiteSetting.types[:enum]]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'raises when it does not in the enum class' do
|
|
||||||
expect {
|
|
||||||
settings.type_supervisor.to_db_value(:type_enum_class, 'random')
|
|
||||||
}.to raise_error Discourse::InvalidParameters
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'validates value by validator' do
|
|
||||||
expect(settings.type_supervisor.to_db_value(:type_validator, 1)).to eq [1, SiteSetting.types[:integer]]
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'raises when the validator says so' do
|
|
||||||
expect {
|
|
||||||
settings.type_supervisor.to_db_value(:type_validator, 11)
|
|
||||||
}.to raise_error Discourse::InvalidParameters
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'tries invoke validate methods' do
|
|
||||||
settings.type_supervisor.expects(:validate_type_mock_validate_method).with('no')
|
|
||||||
settings.type_supervisor.to_db_value(:type_mock_validate_method, 'no')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.to_rb_value' do
|
|
||||||
let(:true_val) { 't' }
|
|
||||||
let(:false_val) { 'f' }
|
|
||||||
|
|
||||||
it 'the type can be overriden by a parameter' do
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_null, '1', SiteSetting.types[:integer])).to eq(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns nil value' do
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_null, '1')).to eq nil
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_null, 1)).to eq nil
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_null, 'null')).to eq nil
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_null, 'nil')).to eq nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns true when it is true or `t` or `true`' do
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_true, true)).to eq true
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_true, 't')).to eq true
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_true, 'true')).to eq true
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns false if not one of `true` value' do
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_true, 'tr')).to eq false
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_true, '')).to eq false
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_true, nil)).to eq false
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_true, false)).to eq false
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_true, 'f')).to eq false
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_true, 'false')).to eq false
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns float value' do
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_float, 1.2)).to eq 1.2
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_float, 1)).to eq 1.0
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_float, '2.2')).to eq 2.2
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_float, '2')).to eq 2
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns string value' do
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_string, 'a')).to eq 'a'
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_string, 2)).to eq '2'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns value with string default' do
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_enum_default_string, 2)).to eq '2'
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_enum_default_string, '2')).to eq '2'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns value with a custom type' do
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_custom, 2)).to eq 2
|
|
||||||
expect(settings.type_supervisor.to_rb_value(:type_custom, '2|3')).to eq '2|3'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.type_hash' do
|
|
||||||
class TestEnumClass2
|
|
||||||
def self.valid_value?(v)
|
|
||||||
self.values.include?(v)
|
|
||||||
end
|
|
||||||
def self.values
|
|
||||||
['a', 'b']
|
|
||||||
end
|
|
||||||
def self.translate_names?
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
before do
|
|
||||||
settings.setting(:type_null, nil)
|
|
||||||
settings.setting(:type_int, 1)
|
|
||||||
settings.setting(:type_true, true)
|
|
||||||
settings.setting(:type_float, 2.3232)
|
|
||||||
settings.setting(:type_string, 'string')
|
|
||||||
settings.setting(:type_url_list, 'string', type: 'url_list')
|
|
||||||
settings.setting(:type_enum_choices, '2', type: 'enum', choices: ['1', '2'])
|
|
||||||
settings.setting(:type_enum_class, 'a', enum: 'TestEnumClass2')
|
|
||||||
settings.setting(:type_list, 'a', type: 'list', choices: ['a', 'b'])
|
|
||||||
settings.refresh!
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns null type' do
|
|
||||||
expect(settings.type_supervisor.type_hash(:type_null)[:type]).to eq 'null'
|
|
||||||
end
|
|
||||||
it 'returns int type' do
|
|
||||||
expect(settings.type_supervisor.type_hash(:type_int)[:type]).to eq 'integer'
|
|
||||||
end
|
|
||||||
it 'returns bool type' do
|
|
||||||
expect(settings.type_supervisor.type_hash(:type_true)[:type]).to eq 'bool'
|
|
||||||
end
|
|
||||||
it 'returns float type' do
|
|
||||||
expect(settings.type_supervisor.type_hash(:type_float)[:type]).to eq 'float'
|
|
||||||
end
|
|
||||||
it 'returns string type' do
|
|
||||||
expect(settings.type_supervisor.type_hash(:type_string)[:type]).to eq 'string'
|
|
||||||
end
|
|
||||||
it 'returns url_list type' do
|
|
||||||
expect(settings.type_supervisor.type_hash(:type_url_list)[:type]).to eq 'url_list'
|
|
||||||
end
|
|
||||||
it 'returns enum type' do
|
|
||||||
expect(settings.type_supervisor.type_hash(:type_enum_choices)[:type]).to eq 'enum'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns list choices' do
|
|
||||||
expect(settings.type_supervisor.type_hash(:type_list)[:choices]).to eq ['a', 'b']
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns enum choices' do
|
|
||||||
hash = settings.type_supervisor.type_hash(:type_enum_choices)
|
|
||||||
expect(hash[:valid_values]).to eq [{ name: '1', value: '1' }, { name: '2', value: '2' }]
|
|
||||||
expect(hash[:translate_names]).to eq false
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns enum class' do
|
|
||||||
hash = settings.type_supervisor.type_hash(:type_enum_class)
|
|
||||||
expect(hash[:valid_values]).to eq ['a', 'b']
|
|
||||||
expect(hash[:translate_names]).to eq false
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -8,18 +8,26 @@ describe SiteSettings::YamlLoader do
|
||||||
|
|
||||||
def load_yaml(file_arg)
|
def load_yaml(file_arg)
|
||||||
SiteSettings::YamlLoader.new(file_arg).load do |category, name, default, opts|
|
SiteSettings::YamlLoader.new(file_arg).load do |category, name, default, opts|
|
||||||
setting(category, name, default, opts)
|
if opts.delete(:client)
|
||||||
|
client_setting(category, name, default, opts)
|
||||||
|
else
|
||||||
|
setting(category, name, default, opts)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def setting(category, name, default = nil, opts = {})
|
def setting(category, name, default = nil, opts = {})
|
||||||
@settings ||= []
|
@settings ||= []
|
||||||
@client_settings ||= []
|
|
||||||
@settings << name
|
@settings << name
|
||||||
@categories ||= []
|
@categories ||= []
|
||||||
@categories << category
|
@categories << category
|
||||||
@categories.uniq!
|
@categories.uniq!
|
||||||
@client_settings << name if opts.has_key?(:client)
|
end
|
||||||
|
|
||||||
|
def client_setting(category, name, default = nil)
|
||||||
|
@client_settings ||= []
|
||||||
|
@client_settings << name
|
||||||
|
setting(category, name, default)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -28,9 +36,7 @@ describe SiteSettings::YamlLoader do
|
||||||
let(:client) { "#{Rails.root}/spec/fixtures/site_settings/client.yml" }
|
let(:client) { "#{Rails.root}/spec/fixtures/site_settings/client.yml" }
|
||||||
let(:enum) { "#{Rails.root}/spec/fixtures/site_settings/enum.yml" }
|
let(:enum) { "#{Rails.root}/spec/fixtures/site_settings/enum.yml" }
|
||||||
let(:enum_client) { "#{Rails.root}/spec/fixtures/site_settings/enum_client.yml" }
|
let(:enum_client) { "#{Rails.root}/spec/fixtures/site_settings/enum_client.yml" }
|
||||||
let(:deprecated_env) { "#{Rails.root}/spec/fixtures/site_settings/deprecated_env.yml" }
|
let(:env) { "#{Rails.root}/spec/fixtures/site_settings/env.yml" }
|
||||||
let(:deprecated_hidden) { "#{Rails.root}/spec/fixtures/site_settings/deprecated_hidden.yml" }
|
|
||||||
let(:locale_default) { "#{Rails.root}/spec/fixtures/site_settings/locale_default.yml" }
|
|
||||||
|
|
||||||
it "loads simple settings" do
|
it "loads simple settings" do
|
||||||
receiver.expects(:setting).with('category1', 'title', 'My Site', {}).once
|
receiver.expects(:setting).with('category1', 'title', 'My Site', {}).once
|
||||||
|
@ -51,9 +57,9 @@ describe SiteSettings::YamlLoader do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can load client settings" do
|
it "can load client settings" do
|
||||||
receiver.expects(:setting).with('category1', 'title', 'Discourse', client: true)
|
receiver.expects(:client_setting).with('category1', 'title', 'Discourse', {})
|
||||||
receiver.expects(:setting).with('category2', 'tos_url', '', client: true)
|
receiver.expects(:client_setting).with('category2', 'tos_url', '', {})
|
||||||
receiver.expects(:setting).with('category2', 'must_approve_users', false, client: true)
|
receiver.expects(:client_setting).with('category2', 'must_approve_users', false, {})
|
||||||
receiver.load_yaml(client)
|
receiver.load_yaml(client)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -63,22 +69,15 @@ describe SiteSettings::YamlLoader do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can load enum client settings" do
|
it "can load enum client settings" do
|
||||||
receiver.expects(:setting).with do |category, name, default, opts|
|
receiver.expects(:client_setting).with do |category, name, default, opts|
|
||||||
category == ('basics') && name == ('default_locale') && default == ('en') && opts[:enum] == ('LocaleSiteSetting') && opts[:client] == true
|
category == ('basics') && name == ('default_locale') && default == ('en') && opts[:enum] == ('LocaleSiteSetting')
|
||||||
end
|
end
|
||||||
receiver.load_yaml(enum_client)
|
receiver.load_yaml(enum_client)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises deprecation when load settings based on environment" do
|
it "can load settings based on environment" do
|
||||||
expect { receiver.load_yaml(deprecated_env) }.to raise_error(Discourse::Deprecation)
|
receiver.expects(:setting).with('misc', 'port', '', {})
|
||||||
end
|
receiver.expects(:client_setting).with('misc', 'crawl_images', false, {})
|
||||||
|
receiver.load_yaml(env)
|
||||||
it "raises deprecation when hidden property is based on environment" do
|
|
||||||
expect { receiver.load_yaml(deprecated_hidden) }.to raise_error(Discourse::Deprecation)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "can load settings with locale default" do
|
|
||||||
receiver.expects(:setting).with('search', 'min_search_term_length', 3, min: 2, client: true, locale_default: { zh_CN: 2, zh_TW: 2 })
|
|
||||||
receiver.load_yaml(locale_default)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,7 +27,6 @@ describe Admin::SiteSettingsController do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
SiteSetting.setting(:test_setting, "default")
|
SiteSetting.setting(:test_setting, "default")
|
||||||
SiteSetting.refresh!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the value when the param is present' do
|
it 'sets the value when the param is present' do
|
||||||
|
@ -50,7 +49,6 @@ describe Admin::SiteSettingsController do
|
||||||
|
|
||||||
it 'does not allow changing of hidden settings' do
|
it 'does not allow changing of hidden settings' do
|
||||||
SiteSetting.setting(:hidden_setting, "hidden", hidden: true)
|
SiteSetting.setting(:hidden_setting, "hidden", hidden: true)
|
||||||
SiteSetting.refresh!
|
|
||||||
result = xhr :put, :update, id: 'hidden_setting', hidden_setting: 'not allowed'
|
result = xhr :put, :update, id: 'hidden_setting', hidden_setting: 'not allowed'
|
||||||
expect(SiteSetting.hidden_setting).to eq("hidden")
|
expect(SiteSetting.hidden_setting).to eq("hidden")
|
||||||
expect(result.status).to eq(422)
|
expect(result.status).to eq(422)
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
developer:
|
|
||||||
force_hostname:
|
|
||||||
hidden:
|
|
||||||
development: false
|
|
||||||
default: true
|
|
||||||
default: ''
|
|
|
@ -1,8 +0,0 @@
|
||||||
search:
|
|
||||||
min_search_term_length:
|
|
||||||
client: true
|
|
||||||
default: 3
|
|
||||||
locale_default:
|
|
||||||
zh_CN: 2
|
|
||||||
zh_TW: 2
|
|
||||||
min: 2
|
|
|
@ -80,8 +80,8 @@ Spork.prefork do
|
||||||
# and pretend they are default.
|
# and pretend they are default.
|
||||||
# There are a bunch of settings that are seeded, they must be loaded as defaults
|
# There are a bunch of settings that are seeded, they must be loaded as defaults
|
||||||
SiteSetting.current.each do |k, v|
|
SiteSetting.current.each do |k, v|
|
||||||
# skip setting defaults for settings that are in unloaded plugins
|
# skip setting defauls for settings that are in unloaded plugins
|
||||||
SiteSetting.defaults.set_regardless_of_locale(k, v) if SiteSetting.respond_to? k
|
SiteSetting.defaults[k] = v if SiteSetting.respond_to? k
|
||||||
end
|
end
|
||||||
|
|
||||||
require_dependency 'site_settings/local_process_provider'
|
require_dependency 'site_settings/local_process_provider'
|
||||||
|
@ -119,7 +119,6 @@ Spork.prefork do
|
||||||
SiteSetting.provider.all.each do |setting|
|
SiteSetting.provider.all.each do |setting|
|
||||||
SiteSetting.remove_override!(setting.name)
|
SiteSetting.remove_override!(setting.name)
|
||||||
end
|
end
|
||||||
SiteSetting.defaults.site_locale = SiteSettings::DefaultsProvider::DEFAULT_LOCALE
|
|
||||||
|
|
||||||
# very expensive IO operations
|
# very expensive IO operations
|
||||||
SiteSetting.automatically_download_gravatars = false
|
SiteSetting.automatically_download_gravatars = false
|
||||||
|
|
Loading…
Reference in New Issue