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 = @opts[:max]
|
||||||
(max.is_a?(::Integer) || max.is_a?(::Float)) && max != ::Float::INFINITY
|
(max.is_a?(::Integer) || max.is_a?(::Float)) && max != ::Float::INFINITY
|
||||||
end
|
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
|
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:
|
causes_refresh:
|
||||||
default: ""
|
default: ""
|
||||||
refresh: true
|
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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "theme_settings_manager"
|
|
||||||
|
|
||||||
RSpec.describe ThemeSettingsManager do
|
RSpec.describe ThemeSettingsManager do
|
||||||
let!(:theme) { Fabricate(:theme) }
|
let!(:theme) { Fabricate(:theme) }
|
||||||
|
|
||||||
|
@ -12,8 +10,6 @@ RSpec.describe ThemeSettingsManager do
|
||||||
theme.settings
|
theme.settings
|
||||||
end
|
end
|
||||||
|
|
||||||
before { SiteSetting.experimental_objects_type_for_theme_settings = true }
|
|
||||||
|
|
||||||
describe "Enum" do
|
describe "Enum" do
|
||||||
it "only accepts values from its choices" do
|
it "only accepts values from its choices" do
|
||||||
enum_setting = theme_settings[:enum_setting]
|
enum_setting = theme_settings[:enum_setting]
|
||||||
|
@ -186,21 +182,4 @@ RSpec.describe ThemeSettingsManager do
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Reference in New Issue