DEV: Change category type to categories type for theme object schema (#26339)

Why this change?

This is a follow-up to 86b2e3aa3e8be30a308f1bff3664d76c5d56057a.

Basically, we want to allow people to select more than 1 category as well.

What does this change do?

1. Change `type: category` to `type: categories` and support `min` and `max`
   validations for `type: categories`.

2. Fix the `<SchemaThemeSetting::Types::Categories>` component to support the
   `min` and `max` validations and switch it to use the `<CategorySelector>` component
   instead of the `<CategoryChooser>` component which only supports selecting one category.
This commit is contained in:
Alan Guo Xiang Tan
2024-03-27 10:54:30 +08:00
committed by GitHub
parent 0df50a7e5d
commit 476d91d233
19 changed files with 387 additions and 100 deletions

View File

@ -15,7 +15,7 @@ RSpec.describe ThemeSettingsObjectValidator do
},
},
category_property: {
type: "category",
type: "categories",
required: true,
},
links: {
@ -49,10 +49,10 @@ RSpec.describe ThemeSettingsObjectValidator do
objects: [
{
title: "1234",
category_property: category.id,
category_property: [category.id],
links: [{ position: 1, float: 4.5 }, { position: "string", float: 12 }],
},
{ title: "12345678910", category_property: 99_999_999, links: [{ float: 5 }] },
{ title: "12345678910", category_property: [99_999_999], links: [{ float: 5 }] },
],
)
@ -63,7 +63,7 @@ RSpec.describe ThemeSettingsObjectValidator do
"The property at JSON Pointer '/0/links/1/position' must be an integer.",
"The property at JSON Pointer '/0/links/1/float' must be smaller than or equal to 11.5.",
"The property at JSON Pointer '/1/title' must be at most 10 characters long.",
"The property at JSON Pointer '/1/category_property' must be a valid category id.",
"The property at JSON Pointer '/1/category_property' must be an array of valid category ids.",
"The property at JSON Pointer '/1/links/0/position' must be present.",
"The property at JSON Pointer '/1/links/0/float' must be larger than or equal to 5.5.",
],
@ -1028,18 +1028,24 @@ RSpec.describe ThemeSettingsObjectValidator do
end
context "for category properties" do
it "should not return any error message when the value of the property is a valid id of a category record" do
category = Fabricate(:category)
fab!(:category_1) { Fabricate(:category) }
fab!(:category_2) { Fabricate(:category) }
schema = { name: "section", properties: { category_property: { type: "category" } } }
it "should not return any error message when the value of the property is an array of valid category ids" do
schema = { name: "section", properties: { category_property: { type: "categories" } } }
expect(
described_class.new(schema: schema, object: { category_property: category.id }).validate,
described_class.new(
schema: schema,
object: {
category_property: [category_1.id, category_2.id],
},
).validate,
).to eq({})
end
it "should not return any error messages when the value is not present and it's not required in the schema" do
schema = { name: "section", properties: { category_property: { type: "category" } } }
schema = { name: "section", properties: { category_property: { type: "categories" } } }
expect(described_class.new(schema: schema, object: {}).validate).to eq({})
end
@ -1048,7 +1054,7 @@ RSpec.describe ThemeSettingsObjectValidator do
name: "section",
properties: {
category_property: {
type: "category",
type: "categories",
required: true,
},
},
@ -1059,30 +1065,51 @@ RSpec.describe ThemeSettingsObjectValidator do
expect(errors["/category_property"].full_messages).to contain_exactly("must be present")
end
it "should return the right hash of error messages when value of property is not an integer" do
schema = { name: "section", properties: { category_property: { type: "category" } } }
it "should return the right hash of error messages when value of property contains an array where not all values are integers" do
schema = { name: "section", properties: { category_property: { type: "categories" } } }
errors =
described_class.new(schema: schema, object: { category_property: "string" }).validate
described_class.new(schema: schema, object: { category_property: ["string"] }).validate
expect(errors.keys).to eq(["/category_property"])
expect(errors["/category_property"].full_messages).to contain_exactly(
"must be a valid category id",
"must be an array of valid category ids",
)
end
it "should return the right hash of error messages when value of property is not a valid id of a category record" do
category = Fabricate(:category)
it "should return the right hash of error messages when number of category ids does not satisfy min or max validations" do
schema = {
name: "section",
properties: {
category_property: {
type: "category",
type: "categories",
validations: {
min: 1,
max: 2,
},
},
},
}
errors = described_class.new(schema: schema, object: { category_property: [] }).validate
expect(errors.keys).to eq(["/category_property"])
expect(errors["/category_property"].full_messages).to contain_exactly(
"must have at least 1 category ids",
)
end
it "should return the right hash of error messages when value of property is not an array of valid category ids" do
schema = {
name: "section",
properties: {
category_property: {
type: "categories",
},
category_property_2: {
type: "category",
type: "categories",
},
child_categories: {
type: "objects",
@ -1090,7 +1117,7 @@ RSpec.describe ThemeSettingsObjectValidator do
name: "child_category",
properties: {
category_property_3: {
type: "category",
type: "categories",
},
},
},
@ -1098,36 +1125,34 @@ RSpec.describe ThemeSettingsObjectValidator do
},
}
object = {
category_property: [99_999_999, category_1.id],
category_property_2: [99_999_999],
child_categories: [
{ category_property_3: [99_999_999, category_2.id] },
{ category_property_3: [category_2.id] },
],
}
queries =
track_sql_queries do
errors =
described_class.new(
schema: schema,
object: {
category_property: 99_999_999,
category_property_2: 99_999_999,
child_categories: [
{ category_property_3: 99_999_999 },
{ category_property_3: category.id },
],
},
).validate
errors = described_class.new(schema:, object:).validate
expect(errors.keys).to eq(
%w[/category_property /category_property_2 /child_categories/0/category_property_3],
)
expect(errors["/category_property"].full_messages).to contain_exactly(
"must be a valid category id",
"must be an array of valid category ids",
)
expect(errors["/category_property_2"].full_messages).to contain_exactly(
"must be a valid category id",
"must be an array of valid category ids",
)
expect(
errors["/child_categories/0/category_property_3"].full_messages,
).to contain_exactly("must be a valid category id")
).to contain_exactly("must be an array of valid category ids")
end
# only 1 SQL query should be executed to check if category ids are valid