mirror of
https://github.com/discourse/discourse.git
synced 2025-04-29 05:14:34 +08:00
DEV: Add property value validation to ThemeSettingsObjectValidator (#25718)
Why this change? This change adds property value validation to `ThemeSettingsObjectValidator` for the following types: "string", "integer", "float", "boolean", "enum". Note that this class is not being used anywhere yet and is still in development.
This commit is contained in:
parent
bdd91b3928
commit
a64f558f32
@ -136,6 +136,12 @@ en:
|
|||||||
string_value_not_valid_max: "It must be at most %{max} characters long."
|
string_value_not_valid_max: "It must be at most %{max} characters long."
|
||||||
objects:
|
objects:
|
||||||
required: "must be present"
|
required: "must be present"
|
||||||
|
invalid_type: "%{type} is not a valid type"
|
||||||
|
not_valid_string_value: "must be a string"
|
||||||
|
not_valid_integer_value: "must be an integer"
|
||||||
|
not_valid_float_value: "must be a float"
|
||||||
|
not_valid_boolean_value: "must be a boolean"
|
||||||
|
not_valid_enum_value: "must be one of the following: %{choices}"
|
||||||
locale_errors:
|
locale_errors:
|
||||||
top_level_locale: "The top level key in a locale file must match the locale name"
|
top_level_locale: "The top level key in a locale file must match the locale name"
|
||||||
invalid_yaml: "Translation YAML invalid"
|
invalid_yaml: "Translation YAML invalid"
|
||||||
|
@ -9,7 +9,7 @@ class ThemeSettingsObjectValidator
|
|||||||
end
|
end
|
||||||
|
|
||||||
def validate
|
def validate
|
||||||
validate_required_properties
|
validate_properties
|
||||||
|
|
||||||
@properties.each do |property_name, property_attributes|
|
@properties.each do |property_name, property_attributes|
|
||||||
if property_attributes[:type] == "objects"
|
if property_attributes[:type] == "objects"
|
||||||
@ -28,12 +28,56 @@ class ThemeSettingsObjectValidator
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def validate_required_properties
|
def validate_properties
|
||||||
@properties.each do |property_name, property_attributes|
|
@properties.each do |property_name, property_attributes|
|
||||||
if property_attributes[:required] && @object[property_name].nil?
|
next if property_attributes[:required] && validate_required_property(property_name)
|
||||||
@errors[property_name] ||= []
|
validate_property_type(property_attributes, property_name)
|
||||||
@errors[property_name] << I18n.t("themes.settings_errors.objects.required")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_property_type(property_attributes, property_name)
|
||||||
|
value = @object[property_name]
|
||||||
|
type = property_attributes[:type]
|
||||||
|
|
||||||
|
return if (value.nil? && type != "enum")
|
||||||
|
return if type == "objects"
|
||||||
|
|
||||||
|
is_value_valid =
|
||||||
|
case type
|
||||||
|
when "string"
|
||||||
|
value.is_a?(String)
|
||||||
|
when "integer"
|
||||||
|
value.is_a?(Integer)
|
||||||
|
when "float"
|
||||||
|
value.is_a?(Float) || value.is_a?(Integer)
|
||||||
|
when "boolean"
|
||||||
|
[true, false].include?(value)
|
||||||
|
when "enum"
|
||||||
|
property_attributes[:choices].include?(value)
|
||||||
|
else
|
||||||
|
add_error(property_name, I18n.t("themes.settings_errors.objects.invalid_type", type:))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if !is_value_valid
|
||||||
|
add_error(
|
||||||
|
property_name,
|
||||||
|
I18n.t("themes.settings_errors.objects.not_valid_#{type}_value", property_attributes),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_required_property(property_name)
|
||||||
|
if @object[property_name].nil?
|
||||||
|
add_error(property_name, I18n.t("themes.settings_errors.objects.required"))
|
||||||
|
true
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_error(property_name, error)
|
||||||
|
@errors[property_name] ||= []
|
||||||
|
@errors[property_name] << error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
RSpec.describe ThemeSettingsObjectValidator do
|
RSpec.describe ThemeSettingsObjectValidator do
|
||||||
describe "#validate" do
|
describe "#validate" do
|
||||||
it "should return the right array of error messages when properties are required but missing" do
|
it "should return the right hash of error messages when properties are required but missing" do
|
||||||
schema = {
|
schema = {
|
||||||
name: "section",
|
name: "section",
|
||||||
properties: {
|
properties: {
|
||||||
@ -68,5 +68,113 @@ RSpec.describe ThemeSettingsObjectValidator do
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "for enum properties" do
|
||||||
|
let(:schema) do
|
||||||
|
{
|
||||||
|
name: "section",
|
||||||
|
properties: {
|
||||||
|
enum_property: {
|
||||||
|
type: "enum",
|
||||||
|
choices: ["choice 1", 2, false],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not return any error messages when the value of the property is in the enum" do
|
||||||
|
expect(
|
||||||
|
described_class.new(schema: schema, object: { enum_property: "choice 1" }).validate,
|
||||||
|
).to eq({})
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the right hash of error messages when value of property is not in the enum" do
|
||||||
|
expect(
|
||||||
|
described_class.new(schema: schema, object: { enum_property: "random_value" }).validate,
|
||||||
|
).to eq(enum_property: ["must be one of the following: [\"choice 1\", 2, false]"])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the right hash of error messages when enum property is not present" do
|
||||||
|
expect(described_class.new(schema: schema, object: {}).validate).to eq(
|
||||||
|
enum_property: ["must be one of the following: [\"choice 1\", 2, false]"],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for boolean properties" do
|
||||||
|
let(:schema) { { name: "section", properties: { boolean_property: { type: "boolean" } } } }
|
||||||
|
|
||||||
|
it "should not return any error messages when the value of the property is of type boolean" do
|
||||||
|
expect(
|
||||||
|
described_class.new(schema: schema, object: { boolean_property: true }).validate,
|
||||||
|
).to eq({})
|
||||||
|
|
||||||
|
expect(
|
||||||
|
described_class.new(schema: schema, object: { boolean_property: false }).validate,
|
||||||
|
).to eq({})
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the right hash of error messages when value of property is not of type boolean" do
|
||||||
|
expect(
|
||||||
|
described_class.new(schema: schema, object: { boolean_property: "string" }).validate,
|
||||||
|
).to eq(boolean_property: ["must be a boolean"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for float properties" do
|
||||||
|
let(:schema) { { name: "section", properties: { float_property: { type: "float" } } } }
|
||||||
|
|
||||||
|
it "should not return any error messages when the value of the property is of type integer or float" do
|
||||||
|
expect(described_class.new(schema: schema, object: { float_property: 1.5 }).validate).to eq(
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(described_class.new(schema: schema, object: { float_property: 1 }).validate).to eq(
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the right hash of error messages when value of property is not of type float" do
|
||||||
|
expect(
|
||||||
|
described_class.new(schema: schema, object: { float_property: "string" }).validate,
|
||||||
|
).to eq(float_property: ["must be a float"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for integer properties" do
|
||||||
|
let(:schema) { { name: "section", properties: { integer_property: { type: "integer" } } } }
|
||||||
|
|
||||||
|
it "should not return any error messages when the value of the property is of type integer" do
|
||||||
|
expect(described_class.new(schema: schema, object: { integer_property: 1 }).validate).to eq(
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the right hash of error messages when value of property is not of type integer" do
|
||||||
|
expect(
|
||||||
|
described_class.new(schema: schema, object: { integer_property: "string" }).validate,
|
||||||
|
).to eq(integer_property: ["must be an integer"])
|
||||||
|
|
||||||
|
expect(
|
||||||
|
described_class.new(schema: schema, object: { integer_property: 1.0 }).validate,
|
||||||
|
).to eq(integer_property: ["must be an integer"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for string properties" do
|
||||||
|
let(:schema) { { name: "section", properties: { string_property: { type: "string" } } } }
|
||||||
|
|
||||||
|
it "should not return any error messages when the value of the property is of type string" do
|
||||||
|
expect(
|
||||||
|
described_class.new(schema: schema, object: { string_property: "string" }).validate,
|
||||||
|
).to eq({})
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the right hash of error messages when value of property is not of type string" do
|
||||||
|
expect(described_class.new(schema: schema, object: { string_property: 1 }).validate).to eq(
|
||||||
|
string_property: ["must be a string"],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user