DEV: Introduce experimental type: objects theme setting (#25538)

Why this change?

This commit introduces an experimental `type: objects` theme setting
which will allow theme developers to store a collection of objects as
JSON in the database. Currently, the feature is still in development and
this commit is simply setting up the ground work for us to introduce the
feature in smaller pieces.

What does this change do?

1. Adds a `json_value` column as `jsonb` data type to the `theme_settings` table.
2. Adds a `experimental_objects_type_for_theme_settings` site setting to
   determine whether `ThemeSetting` records of with the `objects` data
   type can be created.
3. Updates `ThemeSettingsManager` to support read/write access from the
   `ThemeSettings#json_value` column.
This commit is contained in:
Alan Guo Xiang Tan
2024-02-08 10:20:59 +08:00
committed by GitHub
parent 8eb4bf07a6
commit 9f884cdaab
36 changed files with 132 additions and 30 deletions
+13
View File
@@ -84,3 +84,16 @@ 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
+19
View File
@@ -12,6 +12,8 @@ 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]
@@ -184,4 +186,21 @@ 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
+2 -1
View File
@@ -7,6 +7,7 @@ RSpec.describe ThemeField do
before do
SvgSprite.clear_plugin_svg_sprite_cache!
ThemeJavascriptCompiler.disable_terser!
SiteSetting.experimental_objects_type_for_theme_settings = true
end
after { ThemeJavascriptCompiler.enable_terser! }
@@ -385,7 +386,7 @@ HTML
it "generates errors when invalid type is passed" do
field = create_yaml_field(get_fixture("invalid"))
expect(field.error).to include(
I18n.t("#{key}.data_type_not_a_number", name: "invalid_type_setting"),
I18n.t("#{key}.data_type_inclusion", name: "invalid_type_setting"),
)
end
+26
View File
@@ -0,0 +1,26 @@
# frozen_string_literal: true
RSpec.describe ThemeSetting do
fab!(:theme)
context "for validations" do
it "should be invalid when setting data_type to objects and `experimental_objects_type_for_theme_settings` is disabled" do
SiteSetting.experimental_objects_type_for_theme_settings = false
theme_setting =
ThemeSetting.new(name: "test", data_type: ThemeSetting.types[:objects], theme:)
expect(theme_setting.valid?).to eq(false)
expect(theme_setting.errors[:data_type]).to contain_exactly("is not included in the list")
end
it "should be valid when setting data_type to objects and `experimental_objects_type_for_theme_settings` is enabled" do
SiteSetting.experimental_objects_type_for_theme_settings = true
theme_setting =
ThemeSetting.new(name: "test", data_type: ThemeSetting.types[:objects], theme:)
expect(theme_setting.valid?).to eq(true)
end
end
end