mirror of
https://github.com/discourse/discourse.git
synced 2025-05-29 11:34:05 +08:00
DEV: Validate objects when updating typed objects theme settings (#25902)
Why this change? This change ensures that we validate the value of the new objects when updating typed objects theme settings.
This commit is contained in:

committed by
GitHub

parent
42d203d773
commit
afb0adf48d
@ -6,7 +6,7 @@ class ThemeSettingsManager::Objects < ThemeSettingsManager
|
|||||||
end
|
end
|
||||||
|
|
||||||
def value=(objects)
|
def value=(objects)
|
||||||
# TODO: Validate the objects against the schema
|
ensure_is_valid_value!(objects)
|
||||||
|
|
||||||
record = has_record? ? db_record : create_record!
|
record = has_record? ? db_record : create_record!
|
||||||
record.json_value = objects
|
record.json_value = objects
|
||||||
|
@ -61,7 +61,7 @@ class ThemeSettingsObjectValidator
|
|||||||
end
|
end
|
||||||
|
|
||||||
def initialize(schema:, object:, json_pointer_prefix: "", errors: {}, valid_ids_lookup: {})
|
def initialize(schema:, object:, json_pointer_prefix: "", errors: {}, valid_ids_lookup: {})
|
||||||
@object = object
|
@object = object.with_indifferent_access
|
||||||
@schema_name = schema[:name]
|
@schema_name = schema[:name]
|
||||||
@properties = schema[:properties]
|
@properties = schema[:properties]
|
||||||
@errors = errors
|
@errors = errors
|
||||||
|
33
spec/fixtures/theme_settings/objects_settings.yaml
vendored
Normal file
33
spec/fixtures/theme_settings/objects_settings.yaml
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
objects_setting:
|
||||||
|
type: objects
|
||||||
|
default:
|
||||||
|
- name: "section 1"
|
||||||
|
links:
|
||||||
|
- name: "link 1"
|
||||||
|
url: "http://example.com"
|
||||||
|
- name: "link 2"
|
||||||
|
url: "http://example.com"
|
||||||
|
- name: "section 2"
|
||||||
|
links:
|
||||||
|
- name: "link 3"
|
||||||
|
url: "http://example.com"
|
||||||
|
- name: "link 4"
|
||||||
|
url: "http://example.com"
|
||||||
|
schema:
|
||||||
|
name: sections
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
links:
|
||||||
|
type: objects
|
||||||
|
schema:
|
||||||
|
name: link
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
validations:
|
||||||
|
max_length: 20
|
||||||
|
url:
|
||||||
|
type: string
|
@ -3,35 +3,51 @@
|
|||||||
RSpec.describe ThemeSettingsManager::Objects do
|
RSpec.describe ThemeSettingsManager::Objects do
|
||||||
fab!(:theme)
|
fab!(:theme)
|
||||||
|
|
||||||
|
let(:objects_setting) do
|
||||||
|
yaml = File.read("#{Rails.root}/spec/fixtures/theme_settings/objects_settings.yaml")
|
||||||
|
field = theme.set_field(target: :settings, name: "yaml", value: yaml)
|
||||||
|
theme.save!
|
||||||
|
theme.settings[:objects_setting]
|
||||||
|
end
|
||||||
|
|
||||||
before { SiteSetting.experimental_objects_type_for_theme_settings = true }
|
before { SiteSetting.experimental_objects_type_for_theme_settings = true }
|
||||||
|
|
||||||
it "can store a list of objects" do
|
it "can store a list of objects" do
|
||||||
objects_setting =
|
new_value = [
|
||||||
described_class.new(
|
{
|
||||||
"some_objects_setting",
|
"name" => "section 3",
|
||||||
[{ "title" => "Some title", "description" => "Some description" }],
|
"links" => [
|
||||||
theme,
|
{ "name" => "section 3 link 1", "url" => "https://section3link1.com" },
|
||||||
schema: {
|
{ "name" => "section 3 link 2" },
|
||||||
name: "Some Object",
|
],
|
||||||
fields: {
|
|
||||||
title: {
|
|
||||||
type: "string",
|
|
||||||
},
|
},
|
||||||
description: {
|
{
|
||||||
type: "string",
|
"name" => "section 4",
|
||||||
|
"links" => [{ "name" => "section 4 link 1", "url" => "https://section4link1.com" }],
|
||||||
},
|
},
|
||||||
},
|
]
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(objects_setting.value).to eq(
|
objects_setting.value = new_value
|
||||||
[{ "title" => "Some title", "description" => "Some description" }],
|
|
||||||
)
|
|
||||||
|
|
||||||
objects_setting.value = [{ title: "title 1", description: "description 1" }]
|
expect(theme.reload.settings[:objects_setting].value).to eq(new_value)
|
||||||
|
end
|
||||||
|
|
||||||
expect(objects_setting.value).to eq(
|
it "raises the right error when there are objects which are not valid" do
|
||||||
[{ "title" => "title 1", "description" => "description 1" }],
|
new_value = [
|
||||||
|
{ "name" => "section 3", "links" => [{ "url" => "https://some.url.no.name" }] },
|
||||||
|
{
|
||||||
|
"links" => [
|
||||||
|
{
|
||||||
|
"name" => "some name that exceeds the max length of 20 characters",
|
||||||
|
"url" => "https://some.url",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
expect { objects_setting.value = new_value }.to raise_error(
|
||||||
|
Discourse::InvalidParameters,
|
||||||
|
"The property at JSON Pointer '/0/links/0/name' must be present. The property at JSON Pointer '/1/name' must be present. The property at JSON Pointer '/1/links/0/name' must be at most 20 characters long.",
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user