diff --git a/lib/intercom/traits/api_resource.rb b/lib/intercom/traits/api_resource.rb index 52707794..68675863 100644 --- a/lib/intercom/traits/api_resource.rb +++ b/lib/intercom/traits/api_resource.rb @@ -40,7 +40,9 @@ def to_hash def to_submittable_hash submittable_hash = {} to_hash.each do |attribute, value| - submittable_hash[attribute] = value if submittable_attribute?(attribute, value) + next unless submittable_attribute?(attribute, value) + + submittable_hash[attribute] = value.respond_to?(:to_submittable_hash) ? value.to_submittable_hash : value end submittable_hash end diff --git a/lib/intercom/traits/dirty_tracking.rb b/lib/intercom/traits/dirty_tracking.rb index 0d120094..d155c2d9 100644 --- a/lib/intercom/traits/dirty_tracking.rb +++ b/lib/intercom/traits/dirty_tracking.rb @@ -22,7 +22,14 @@ def mark_field_as_changed!(field_name) def field_changed?(field_name) @changed_fields ||= Set.new - @changed_fields.include?(field_name.to_s) + field = instance_variable_get("@#{field_name}") + if field.respond_to?(:field_changed?) + field.to_hash.any? do |attribute, _| + field.field_changed?(attribute) + end + else + @changed_fields.include?(field_name.to_s) + end end def instance_variables_excluding_dirty_tracking_field diff --git a/spec/unit/intercom/traits/api_resource_spec.rb b/spec/unit/intercom/traits/api_resource_spec.rb index b5724556..aabb5d01 100644 --- a/spec/unit/intercom/traits/api_resource_spec.rb +++ b/spec/unit/intercom/traits/api_resource_spec.rb @@ -17,7 +17,15 @@ 'metadata' => { 'type' => 'user', 'color' => 'cyan' - } } + }, + 'nested_fields' => { + 'type' => 'nested_fields_content', + 'field_1' => { + 'type' => 'field_content', + 'name' => 'Nested Field' + } + } + } end let(:object_hash) do @@ -35,6 +43,13 @@ metadata: { type: 'user', color: 'cyan' + }, + nested_fields: { + type: 'nested_fields_content', + field_1: { + type: 'field_content', + name: 'Nested Field' + } } } end @@ -97,7 +112,7 @@ it 'an initialized ApiResource is equal to one generated from a response' do class ConcreteApiResource; include Intercom::Traits::ApiResource; end initialized_api_resource = ConcreteApiResource.new(object_json) - except(object_json, 'type').keys.each do |attribute| + except(object_json, 'type', 'nested_fields').keys.each do |attribute| assert_equal initialized_api_resource.send(attribute), api_resource.send(attribute) end end @@ -107,12 +122,28 @@ class ConcreteApiResource; include Intercom::Traits::ApiResource; end api_resource.from_hash(object_hash) initialized_api_resource = ConcreteApiResource.new(object_hash) - - except(object_json, 'type').keys.each do |attribute| + except(object_json, 'type', 'nested_fields').keys.each do |attribute| assert_equal initialized_api_resource.send(attribute), api_resource.send(attribute) end end + it 'correctly generates submittable hash when no updates' do + assert_equal api_resource.to_submittable_hash, {} + end + + it 'correctly generates submittable hash when there are updates' do + api_resource.name = 'SuperSuite updated' + api_resource.nested_fields.field_1.name = 'Updated Name' + assert_equal api_resource.to_submittable_hash, { + 'name' => 'SuperSuite updated', + 'nested_fields' => { + 'field_1' => { + 'name' => 'Updated Name' + } + } + } + end + def except(h, *keys) keys.each { |key| h.delete(key) } h