require 'helper' class AxleAttributes::Serializations::SerializeManyTest < ActiveSupport::TestCase class Girlfriend < Superstore::Base include AxleAttributes::SerializedChild has_attribute :color, type: :string, index: true has_attribute :height, type: :integer, index: false validates :color, inclusion: {in: ['red', 'blue']} end class TestModel < Business serialize_many :girlfriends, class_name: 'AxleAttributes::Serializations::SerializeManyTest::Girlfriend' end test 'attributes' do assert_nil TestModel.attributes['girlfriends_json'] refute_nil TestModel.attributes['girlfriends_count'] refute_nil TestModel.attributes['girlfriends.color'] refute_nil TestModel.attributes['girlfriends.height'] assert_equal 'girlfriends', TestModel.attributes['girlfriends.height'].nested_path assert TestModel.new.respond_to?(:girlfriends) assert TestModel.new.respond_to?(:girlfriends=) end test 'index mapping' do contacts_mapping = TestModel.elastic_index.mapping[:properties]['girlfriends'] refute_nil contacts_mapping assert_equal :nested, contacts_mapping[:type] assert_equal Girlfriend.attributes['color'].index_mapping, contacts_mapping[:properties]['color'] end test 'serialization_reflections' do refute_nil TestModel.serialization_reflections[:girlfriends] end test 'writer on empty' do girlfriend = Girlfriend.new(color: 'blue') record = TestModel.new record.girlfriends = [girlfriend] assert_equal 1, record.girlfriends_count assert_equal [girlfriend], record.girlfriends assert_equal 'blue', record[:girlfriends].first['color'] assert_kind_of String, record[:girlfriends].first['created_at'] assert_equal record.child_serialization(:girlfriends), record.girlfriends.first.serialization_instance end test 'writer on existing record' do original_girlfriend = Girlfriend.new(id: '5', color: 'blue') updated_girlfriend = Girlfriend.new(id: '5', color: 'green') record = TestModel.new girlfriends: [original_girlfriend] record.girlfriends = [updated_girlfriend] assert_equal 1, record.girlfriends_count assert_equal 'green', record.girlfriends.first.color assert_equal original_girlfriend.created_at, record.girlfriends.first.created_at end test 'writer on record replacement' do original_girlfriend = Girlfriend.new(id: '5', color: 'blue') new_girlfriend = Girlfriend.new(id: '10', color: 'green') record = TestModel.new girlfriends: [original_girlfriend] record.girlfriends = [new_girlfriend] assert_equal 1, record.girlfriends_count assert_equal 'green', record.girlfriends.first.color assert_equal new_girlfriend, record.girlfriends.first end test 'writer with nil' do record = TestModel.new girlfriends: nil assert_equal Set.new, record.provided_set assert_equal Hash.new, record.changes end test 'attributes_writer updates existing' do girlfriend = Girlfriend.new(id: 'abc', height: 60) record = TestModel.new girlfriends: [girlfriend] record.girlfriends_attributes = [ {'id' => 'abc', height: 68} ] assert_equal [girlfriend.object_id], record.girlfriends.map(&:object_id) assert_equal 68, girlfriend.height end test 'attributes_writer partial write' do keeper_girlfriend = Girlfriend.new(id: 'abc', height: 60) loser_girlfriend = Girlfriend.new(id: 'xyz', height: 48) record = TestModel.new girlfriends: [keeper_girlfriend, loser_girlfriend] record.girlfriends_attributes = [ {'id' => 'xyz', '_destroy' => '1'}, {'id' => 'mno', height: 68} ] assert_equal ['abc', 'mno'].to_set, record.girlfriends.map(&:id).to_set assert record.girlfriends.include?(keeper_girlfriend) assert record.girlfriends.exclude?(loser_girlfriend) new_girlfriend = record.girlfriends.detect { |gf| gf.id == 'mno' } assert_equal 68, new_girlfriend.height end test 'attributes_writer with empty collection' do record = TestModel.new girlfriends_attributes: [] assert_equal Set.new, record.provided_set assert_equal Hash.new, record.changes end test 'read when nil' do record = TestModel.new assert_equal [], record.girlfriends end test 'reader' do record = TestModel.new record[:girlfriends] = [{'id' => '5', 'color' => 'red'}] assert_equal [Girlfriend.new(id: '5')], record.girlfriends assert_equal record.child_serialization(:girlfriends), record.girlfriends.first.serialization_instance end test 'reader_was' do record = TestModel.new record.girlfriends = [{'id' => '5', 'color' => 'red'}] assert_equal [], record.girlfriends_was record.changed_attributes.clear record.girlfriends = [{'id' => '5', 'color' => 'blue'}] assert_equal 1, record.girlfriends_was.size assert_equal 'red', record.girlfriends_was.first.color assert_equal '5', record.girlfriends_was.first.id end test 'validation' do TestModel.new(girlfriends: [Girlfriend.new(color: 'red')]).tap do |record| assert record.valid? end TestModel.new(girlfriends: [Girlfriend.new(color: 'green')]).tap do |record| assert record.invalid? assert_equal ["is not included in the list"], record.errors['girlfriends.color'] end end test 'dirty changed' do girlfriends = [Girlfriend.new(color: 'red', id: '6')] record = TestModel.create! girlfriends: girlfriends record = TestModel.find record.id record.girlfriends = girlfriends refute record.changed? end test 'dirty restore_attributes' do girlfriends = [Girlfriend.new(color: 'red', id: '6')] record = TestModel.create! girlfriends: girlfriends record = TestModel.find record.id record.girlfriends = [{height: 6, id: '6'}] assert_equal 6, record.girlfriends.first.height assert_nil record.girlfriends.first.color record.restore_attributes assert_equal 'red', record.girlfriends.first.color assert_nil record.girlfriends.first.height end test 'reload' do record = TestModel.create! girlfriends: [Girlfriend.new(color: 'red')] record = TestModel.find record.id record.girlfriends = [Girlfriend.new(color: 'blue'), Girlfriend.new(color: 'red')] record.reload assert_equal 1, record.girlfriends.size end end