diff --git a/lib/theme_settings_manager/objects.rb b/lib/theme_settings_manager/objects.rb index 50a7b730ef0..3f51f6293bf 100644 --- a/lib/theme_settings_manager/objects.rb +++ b/lib/theme_settings_manager/objects.rb @@ -6,7 +6,7 @@ class ThemeSettingsManager::Objects < ThemeSettingsManager end def value=(objects) - # TODO: Validate the objects against the schema + ensure_is_valid_value!(objects) record = has_record? ? db_record : create_record! record.json_value = objects diff --git a/lib/theme_settings_object_validator.rb b/lib/theme_settings_object_validator.rb index ab90861c4b6..7463ad3d847 100644 --- a/lib/theme_settings_object_validator.rb +++ b/lib/theme_settings_object_validator.rb @@ -61,7 +61,7 @@ class ThemeSettingsObjectValidator end def initialize(schema:, object:, json_pointer_prefix: "", errors: {}, valid_ids_lookup: {}) - @object = object + @object = object.with_indifferent_access @schema_name = schema[:name] @properties = schema[:properties] @errors = errors diff --git a/spec/fixtures/theme_settings/objects_settings.yaml b/spec/fixtures/theme_settings/objects_settings.yaml new file mode 100644 index 00000000000..e71fa507fae --- /dev/null +++ b/spec/fixtures/theme_settings/objects_settings.yaml @@ -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 \ No newline at end of file diff --git a/spec/lib/theme_settings_manager/objects_spec.rb b/spec/lib/theme_settings_manager/objects_spec.rb index 41858cd27f5..028bcba6fa7 100644 --- a/spec/lib/theme_settings_manager/objects_spec.rb +++ b/spec/lib/theme_settings_manager/objects_spec.rb @@ -3,35 +3,51 @@ RSpec.describe ThemeSettingsManager::Objects do 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 } 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", - }, + new_value = [ + { + "name" => "section 3", + "links" => [ + { "name" => "section 3 link 1", "url" => "https://section3link1.com" }, + { "name" => "section 3 link 2" }, + ], + }, + { + "name" => "section 4", + "links" => [{ "name" => "section 4 link 1", "url" => "https://section4link1.com" }], + }, + ] + + objects_setting.value = new_value + + expect(theme.reload.settings[:objects_setting].value).to eq(new_value) + end + + it "raises the right error when there are objects which are not valid" do + 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).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" }], + 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