From 252dcf636f1fc46249aa5cd10c5d031e93ce278d Mon Sep 17 00:00:00 2001 From: pezholio Date: Tue, 4 Jun 2024 11:32:09 +0100 Subject: [PATCH] Add `ObjectStore::Item` model This inherits the edition model and sets a few defaults to override some Edition defaults. It also contains an `add_field_accessors` callback that reads the configuration for a given item_type and sets the relevant variables using [`store_accessor`][1]. Additionally, if the field is required, we set validation on the object too. [1]: https://api.rubyonrails.org/classes/ActiveRecord/Store.html --- app/models/object_store/item.rb | 33 +++++++++++++++++++ test/factories.rb | 2 +- test/factories/object_store/item.rb | 11 +++++++ .../unit/app/models/object_store/item_test.rb | 30 +++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 app/models/object_store/item.rb create mode 100644 test/factories/object_store/item.rb create mode 100644 test/unit/app/models/object_store/item_test.rb diff --git a/app/models/object_store/item.rb b/app/models/object_store/item.rb new file mode 100644 index 00000000000..c2022f05f53 --- /dev/null +++ b/app/models/object_store/item.rb @@ -0,0 +1,33 @@ +module ObjectStore + class Item < Edition + store_accessor :details, :item_type + + after_initialize :add_field_accessors + + def summary_required? + false + end + + def body_required? + false + end + + def previously_published + false + end + + private + + def add_field_accessors + properties = ObjectStore.fields_for_item_type(item_type) + properties.each_key do |k| + singleton_class.class_eval { store_accessor :details, k } + if ObjectStore.field_is_required?(item_type, k) + singleton_class.class_eval { validates k, presence: true } + end + end + rescue UnknownItemType + # Ignored + end + end +end diff --git a/test/factories.rb b/test/factories.rb index 85db1e3f511..e3ac00143a1 100644 --- a/test/factories.rb +++ b/test/factories.rb @@ -2,4 +2,4 @@ def image_fixture_file @image_fixture_file ||= File.open(Rails.root.join("test/fixtures/minister-of-funk.960x640.jpg")) end -Dir[Rails.root.join("test/factories/*.rb")].sort.each { |f| require f } +Dir[Rails.root.join("test/factories/**/*.rb")].sort.each { |f| require f } diff --git a/test/factories/object_store/item.rb b/test/factories/object_store/item.rb new file mode 100644 index 00000000000..95af595d3eb --- /dev/null +++ b/test/factories/object_store/item.rb @@ -0,0 +1,11 @@ +FactoryBot.define do + factory :object_store_item, class: ObjectStore::Item, parent: :edition do + transient do + item_type { "email_address" } + end + + title { "object-store-item" } + + initialize_with { ObjectStore::Item.new(item_type:) } + end +end diff --git a/test/unit/app/models/object_store/item_test.rb b/test/unit/app/models/object_store/item_test.rb new file mode 100644 index 00000000000..4705a57cfc6 --- /dev/null +++ b/test/unit/app/models/object_store/item_test.rb @@ -0,0 +1,30 @@ +require "test_helper" + +class ObjectStore::ItemTest < ActiveSupport::TestCase + setup do + @item = build(:object_store_item, item_type: "email_address") + end + + test "it creates accessors for an email address" do + @item.email_address = "foo@example.com" + + assert_equal @item.email_address, "foo@example.com" + end + + test "it validates the presence of an email address" do + assert_not @item.valid? + assert @item.errors[:email_address].any? + end + + test "#summary_required? returns false" do + assert_equal @item.summary_required?, false + end + + test "#body_required? returns false" do + assert_equal @item.body_required?, false + end + + test "#previously_published returns false" do + assert_equal @item.previously_published, false + end +end