fix all sorts of issues with random spec order

SiteSetting no longer persisted across tests
This commit is contained in:
Sam
2013-06-23 13:35:06 +10:00
parent 251aca3b00
commit 0b94c3c456
8 changed files with 424 additions and 179 deletions

View File

@@ -1,7 +1,18 @@
require_dependency 'enum'
require_dependency 'site_settings/db_provider'
module SiteSettingExtension
# part 1 of refactor, centralizing the dependency here
def provider=(val)
@provider = val
refresh!
end
def provider
@provider ||= SiteSettings::DbProvider.new(SiteSetting)
end
def types
@types ||= Enum.new(:string, :time, :fixnum, :float, :bool, :null, :enum)
end
@@ -12,7 +23,7 @@ module SiteSettingExtension
def current
@@containers ||= {}
@@containers[RailsMultisite::ConnectionManagement.current_db] ||= {}
@@containers[provider.current_site] ||= {}
end
def defaults
@@ -27,7 +38,10 @@ module SiteSettingExtension
mutex.synchronize do
self.defaults[name] = default
current_value = current.has_key?(name) ? current[name] : default
enums[name] = opts[:enum] if opts[:enum]
if opts[:enum]
enum = opts[:enum]
enums[name] = enum.is_a?(String) ? enum.constantize : enum
end
setup_methods(name, current_value)
end
end
@@ -74,29 +88,21 @@ module SiteSettingExtension
I18n.t("site_settings.#{setting}")
end
# table is not in the db yet, initial migration, etc
def table_exists?
@table_exists = ActiveRecord::Base.connection.table_exists? 'site_settings' if @table_exists == nil
@table_exists
end
def self.client_settings_cache_key
"client_settings_json"
end
# refresh all the site settings
def refresh!
return unless table_exists?
mutex.synchronize do
ensure_listen_for_changes
old = current
all_settings = SiteSetting.select([:name,:value,:data_type])
all_settings = provider.all
new_hash = Hash[*(all_settings.map{|s| [s.name.intern, convert(s.value,s.data_type)]}.to_a.flatten)]
# add defaults
new_hash = defaults.merge(new_hash)
changes,deletions = diff_hash(new_hash, old)
if deletions.length > 0 || changes.length > 0
@@ -129,7 +135,7 @@ module SiteSettingExtension
begin
@last_message_processed = message.global_id
MessageBus.on_connect.call(message.site_id)
SiteSetting.refresh!
refresh!
ensure
MessageBus.on_disconnect.call(message.site_id)
end
@@ -147,14 +153,11 @@ module SiteSettingExtension
end
def remove_override!(name)
return unless table_exists?
SiteSetting.where(name: name).destroy_all
provider.destroy(name)
current[name] = defaults[name]
end
def add_override!(name,val)
return unless table_exists?
setting = SiteSetting.where(name: name).first
type = get_data_type(name, defaults[name])
if type == types[:bool] && val != true && val != false
@@ -173,18 +176,10 @@ module SiteSettingExtension
raise Discourse::InvalidParameters.new(:value) unless enum_class(name).valid_value?(val)
end
if setting
setting.value = val
setting.data_type = type
setting.save
else
SiteSetting.create!(name: name, value: val, data_type: type)
end
provider.save(name, val, type)
@last_message_sent = MessageBus.publish('/site_settings', {process: process_id})
end
protected
def diff_hash(new_hash, old)
@@ -225,7 +220,7 @@ module SiteSettingExtension
when types[:string], types[:enum]
value
when types[:bool]
value == "t"
value == true || value == "t" || value == "true"
when types[:null]
nil
end
@@ -235,16 +230,12 @@ module SiteSettingExtension
def setup_methods(name, current_value)
# trivial multi db support, we can optimize this later
db = RailsMultisite::ConnectionManagement.current_db
@@containers ||= {}
@@containers[db] ||= {}
@@containers[db][name] = current_value
current[name] = current_value
setter = ("#{name}=").sub("?","")
eval "define_singleton_method :#{name} do
c = @@containers[RailsMultisite::ConnectionManagement.current_db]
c = @@containers[provider.current_site]
c = c[name] if c
c
end
@@ -265,7 +256,6 @@ module SiteSettingExtension
end
def enum_class(name)
enums[name] = enums[name].constantize unless enums[name].is_a?(Class)
enums[name]
end

View File

@@ -0,0 +1,65 @@
module SiteSettings; end
class SiteSettings::DbProvider
def initialize(model)
@model = model
end
def all
return [] unless table_exists?
# note, not leaking out AR records, cause I want all editing to happen
# via this API
SqlBuilder.new("select name, data_type, value from #{@model.table_name}").map_exec(OpenStruct)
end
def find(name)
return nil unless table_exists?
# note, not leaking out AR records, cause I want all editing to happen
# via this API
SqlBuilder.new("select name, data_type, value from #{@model.table_name} where name = :name")
.map_exec(OpenStruct, name: name)
.first
end
def save(name, value, data_type)
return unless table_exists?
count = @model.update_all({
name: name,
value: value,
data_type: data_type,
updated_at: Time.now
}, {
name: name
})
if count == 0
@model.create!(name: name, value: value, data_type: data_type)
end
true
end
def destroy(name)
return unless table_exists?
@model.where(name: name).destroy_all
end
def current_site
RailsMultisite::ConnectionManagement.current_db
end
protected
# table is not in the db yet, initial migration, etc
def table_exists?
@table_exists = ActiveRecord::Base.connection.table_exists? @model.table_name if @table_exists == nil
@table_exists
end
end

View File

@@ -0,0 +1,31 @@
module SiteSettings; end
class SiteSettings::LocalProcessProvider
Setting = Struct.new(:name, :value, :data_type)
def initialize
@settings = {}
end
def all
@settings.values
end
def find(name)
@settings[name]
end
def save(name, value, data_type)
@settings[name] = Setting.new(name,value, data_type)
end
def destroy(name)
@settings.delete(name)
end
def current_site
"test"
end
end