DEV: Refactor subclasses in `ThemeSettingsManager` to individual files (#25605)
Why this change? One Ruby class per file improves readability
This commit is contained in:
parent
7ce76143ac
commit
fb0e656cb7
|
@ -112,155 +112,4 @@ class ThemeSettingsManager
|
|||
max = @opts[:max]
|
||||
(max.is_a?(::Integer) || max.is_a?(::Float)) && max != ::Float::INFINITY
|
||||
end
|
||||
|
||||
class Objects < self
|
||||
def value
|
||||
has_record? ? db_record.json_value : default.map!(&:deep_stringify_keys)
|
||||
end
|
||||
|
||||
def value=(objects)
|
||||
# TODO: Validate the objects against the schema
|
||||
|
||||
record = has_record? ? db_record : create_record!
|
||||
record.json_value = objects
|
||||
record.save!
|
||||
record.json_value
|
||||
end
|
||||
end
|
||||
|
||||
class List < self
|
||||
def list_type
|
||||
@opts[:list_type]
|
||||
end
|
||||
end
|
||||
|
||||
class String < self
|
||||
def is_valid_value?(new_value)
|
||||
(@opts[:min]..@opts[:max]).include? new_value.to_s.length
|
||||
end
|
||||
|
||||
def textarea
|
||||
@opts[:textarea]
|
||||
end
|
||||
|
||||
def json_schema
|
||||
begin
|
||||
JSON.parse(@opts[:json_schema])
|
||||
rescue StandardError
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Bool < self
|
||||
def self.cast(value)
|
||||
[true, "true"].include?(value)
|
||||
end
|
||||
|
||||
def value
|
||||
self.class.cast(super)
|
||||
end
|
||||
|
||||
def value=(new_value)
|
||||
new_value = (self.class.cast(new_value)).to_s
|
||||
super(new_value)
|
||||
end
|
||||
end
|
||||
|
||||
class Integer < self
|
||||
def self.cast(value)
|
||||
value.to_i
|
||||
end
|
||||
|
||||
def value
|
||||
self.class.cast(super)
|
||||
end
|
||||
|
||||
def value=(new_value)
|
||||
super(self.class.cast(new_value))
|
||||
end
|
||||
|
||||
def is_valid_value?(new_value)
|
||||
(@opts[:min]..@opts[:max]).include? new_value.to_i
|
||||
end
|
||||
end
|
||||
|
||||
class Float < self
|
||||
def self.cast(value)
|
||||
value.to_f
|
||||
end
|
||||
|
||||
def value
|
||||
self.class.cast(super)
|
||||
end
|
||||
|
||||
def value=(new_value)
|
||||
super(self.class.cast(new_value))
|
||||
end
|
||||
|
||||
def is_valid_value?(new_value)
|
||||
(@opts[:min]..@opts[:max]).include? new_value.to_f
|
||||
end
|
||||
end
|
||||
|
||||
class Enum < self
|
||||
def value
|
||||
val = super
|
||||
match = choices.find { |choice| choice == val || choice.to_s == val }
|
||||
match || val
|
||||
end
|
||||
|
||||
def is_valid_value?(new_value)
|
||||
choices.include?(new_value) || choices.map(&:to_s).include?(new_value)
|
||||
end
|
||||
|
||||
def choices
|
||||
@opts[:choices]
|
||||
end
|
||||
end
|
||||
|
||||
class Upload < self
|
||||
def value
|
||||
has_record? ? cdn_url(db_record.value) : default
|
||||
end
|
||||
|
||||
def default
|
||||
upload_id = default_upload_id
|
||||
return if upload_id.blank?
|
||||
|
||||
cdn_url(upload_id)
|
||||
end
|
||||
|
||||
def value=(new_value)
|
||||
if new_value.present?
|
||||
if new_value == default
|
||||
new_value = default_upload_id
|
||||
else
|
||||
upload = ::Upload.find_by(url: new_value)
|
||||
new_value = upload.id if upload.present?
|
||||
end
|
||||
end
|
||||
|
||||
super(new_value)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cdn_url(upload_id)
|
||||
return if upload_id.blank?
|
||||
|
||||
upload = ::Upload.find_by_id(upload_id.to_i)
|
||||
return if upload.blank?
|
||||
|
||||
Discourse.store.cdn_url(upload.url)
|
||||
end
|
||||
|
||||
def default_upload_id
|
||||
theme_field =
|
||||
theme.theme_fields.find_by(name: @default, type_id: ThemeField.types[:theme_upload_var])
|
||||
return if theme_field.blank?
|
||||
|
||||
theme_field.upload_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ThemeSettingsManager::Bool < ThemeSettingsManager
|
||||
def self.cast(value)
|
||||
[true, "true"].include?(value)
|
||||
end
|
||||
|
||||
def value
|
||||
self.class.cast(super)
|
||||
end
|
||||
|
||||
def value=(new_value)
|
||||
new_value = (self.class.cast(new_value)).to_s
|
||||
super(new_value)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ThemeSettingsManager::Enum < ThemeSettingsManager
|
||||
def value
|
||||
val = super
|
||||
match = choices.find { |choice| choice == val || choice.to_s == val }
|
||||
match || val
|
||||
end
|
||||
|
||||
def is_valid_value?(new_value)
|
||||
choices.include?(new_value) || choices.map(&:to_s).include?(new_value)
|
||||
end
|
||||
|
||||
def choices
|
||||
@opts[:choices]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ThemeSettingsManager::Float < ThemeSettingsManager
|
||||
def self.cast(value)
|
||||
value.to_f
|
||||
end
|
||||
|
||||
def value
|
||||
self.class.cast(super)
|
||||
end
|
||||
|
||||
def value=(new_value)
|
||||
super(self.class.cast(new_value))
|
||||
end
|
||||
|
||||
def is_valid_value?(new_value)
|
||||
(@opts[:min]..@opts[:max]).include? new_value.to_f
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ThemeSettingsManager::Integer < ThemeSettingsManager
|
||||
def self.cast(value)
|
||||
value.to_i
|
||||
end
|
||||
|
||||
def value
|
||||
self.class.cast(super)
|
||||
end
|
||||
|
||||
def value=(new_value)
|
||||
super(self.class.cast(new_value))
|
||||
end
|
||||
|
||||
def is_valid_value?(new_value)
|
||||
(@opts[:min]..@opts[:max]).include? new_value.to_i
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ThemeSettingsManager::List < ThemeSettingsManager
|
||||
def list_type
|
||||
@opts[:list_type]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ThemeSettingsManager::Objects < ThemeSettingsManager
|
||||
def value
|
||||
has_record? ? db_record.json_value : default.map!(&:deep_stringify_keys)
|
||||
end
|
||||
|
||||
def value=(objects)
|
||||
# TODO: Validate the objects against the schema
|
||||
|
||||
record = has_record? ? db_record : create_record!
|
||||
record.json_value = objects
|
||||
record.save!
|
||||
theme.reload
|
||||
record.json_value
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ThemeSettingsManager::String < ThemeSettingsManager
|
||||
def is_valid_value?(new_value)
|
||||
(@opts[:min]..@opts[:max]).include? new_value.to_s.length
|
||||
end
|
||||
|
||||
def textarea
|
||||
@opts[:textarea]
|
||||
end
|
||||
|
||||
def json_schema
|
||||
begin
|
||||
JSON.parse(@opts[:json_schema])
|
||||
rescue StandardError
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ThemeSettingsManager::Upload < ThemeSettingsManager
|
||||
def value
|
||||
has_record? ? cdn_url(db_record.value) : default
|
||||
end
|
||||
|
||||
def default
|
||||
upload_id = default_upload_id
|
||||
return if upload_id.blank?
|
||||
|
||||
cdn_url(upload_id)
|
||||
end
|
||||
|
||||
def value=(new_value)
|
||||
if new_value.present?
|
||||
if new_value == default
|
||||
new_value = default_upload_id
|
||||
else
|
||||
upload = ::Upload.find_by(url: new_value)
|
||||
new_value = upload.id if upload.present?
|
||||
end
|
||||
end
|
||||
|
||||
super(new_value)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cdn_url(upload_id)
|
||||
return if upload_id.blank?
|
||||
|
||||
upload = ::Upload.find_by_id(upload_id.to_i)
|
||||
return if upload.blank?
|
||||
|
||||
Discourse.store.cdn_url(upload.url)
|
||||
end
|
||||
|
||||
def default_upload_id
|
||||
theme_field =
|
||||
theme.theme_fields.find_by(name: @default, type_id: ThemeField.types[:theme_upload_var])
|
||||
return if theme_field.blank?
|
||||
|
||||
theme_field.upload_id
|
||||
end
|
||||
end
|
|
@ -84,16 +84,3 @@ valid_json_schema_setting:
|
|||
causes_refresh:
|
||||
default: ""
|
||||
refresh: true
|
||||
|
||||
valid_objects_setting:
|
||||
type: objects
|
||||
default:
|
||||
- title: "Some title"
|
||||
description: "Some description"
|
||||
schema:
|
||||
name: "Some Object"
|
||||
fields:
|
||||
title:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe ThemeSettingsManager::Objects do
|
||||
fab!(:theme)
|
||||
|
||||
before { SiteSetting.experimental_objects_type_for_theme_settings = true }
|
||||
|
||||
it "can store a list of objects" do
|
||||
objects_setting =
|
||||
described_class.new(
|
||||
"some_objects_setting",
|
||||
[{ "title" => "Some title", "description" => "Some description" }],
|
||||
theme,
|
||||
schema: {
|
||||
name: "Some Object",
|
||||
fields: {
|
||||
title: {
|
||||
type: "string",
|
||||
},
|
||||
description: {
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
expect(objects_setting.value).to eq(
|
||||
[{ "title" => "Some title", "description" => "Some description" }],
|
||||
)
|
||||
|
||||
objects_setting.value = [{ title: "title 1", description: "description 1" }]
|
||||
|
||||
expect(objects_setting.value).to eq(
|
||||
[{ "title" => "title 1", "description" => "description 1" }],
|
||||
)
|
||||
end
|
||||
end
|
|
@ -1,7 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "theme_settings_manager"
|
||||
|
||||
RSpec.describe ThemeSettingsManager do
|
||||
let!(:theme) { Fabricate(:theme) }
|
||||
|
||||
|
@ -12,8 +10,6 @@ RSpec.describe ThemeSettingsManager do
|
|||
theme.settings
|
||||
end
|
||||
|
||||
before { SiteSetting.experimental_objects_type_for_theme_settings = true }
|
||||
|
||||
describe "Enum" do
|
||||
it "only accepts values from its choices" do
|
||||
enum_setting = theme_settings[:enum_setting]
|
||||
|
@ -186,21 +182,4 @@ RSpec.describe ThemeSettingsManager do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ThemeSettingsManager::Objects do
|
||||
it "can store a list of objects" do
|
||||
objects_setting = theme_settings[:valid_objects_setting]
|
||||
|
||||
expect(objects_setting.value).to eq(
|
||||
[{ "title" => "Some title", "description" => "Some description" }],
|
||||
)
|
||||
|
||||
objects_setting.value = [{ title: "title 1", description: "description 1" }]
|
||||
objects_setting = theme.reload.settings[:valid_objects_setting]
|
||||
|
||||
expect(objects_setting.value).to eq(
|
||||
[{ "title" => "title 1", "description" => "description 1" }],
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue