From 4ab9f012b5ea8728bba8516085cd243e32cd786f Mon Sep 17 00:00:00 2001 From: Vincent Pochet Date: Fri, 8 Nov 2024 09:11:41 +0100 Subject: [PATCH] fix(custom_aggregation): Ensure custom properties are stored as Hash (#2781) ## Context In some cases `charge#properties[:custom_properties] `are persisted as a string when the logic expects a `Hash` ## Description This PR makes sure that the properties are always saved as a Hash --- .../filter_charge_model_properties_service.rb | 9 +++++++++ ...er_charge_model_properties_service_spec.rb | 19 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/app/services/charges/filter_charge_model_properties_service.rb b/app/services/charges/filter_charge_model_properties_service.rb index 9770f79bcb7..8cf310f1dd9 100644 --- a/app/services/charges/filter_charge_model_properties_service.rb +++ b/app/services/charges/filter_charge_model_properties_service.rb @@ -11,6 +11,15 @@ def initialize(charge:, properties:) def call result.properties = slice_properties || {} + + if result.properties[:custom_properties].present? && result.properties[:custom_properties].is_a?(String) + result.properties[:custom_properties] = begin + JSON.parse(result.properties[:custom_properties]) + rescue JSON::ParserError + {} + end + end + result end diff --git a/spec/services/charges/filter_charge_model_properties_service_spec.rb b/spec/services/charges/filter_charge_model_properties_service_spec.rb index 496a8bfd224..2ad61f5e40c 100644 --- a/spec/services/charges/filter_charge_model_properties_service_spec.rb +++ b/spec/services/charges/filter_charge_model_properties_service_spec.rb @@ -24,10 +24,12 @@ per_transaction_max_amount: 100, per_transaction_min_amount: 10, volume_ranges: [{from_value: 0, to_value: 100, per_unit_amount: '2', flat_amount: '1'}], - custom_properties: {rate: '20'} + custom_properties: } end + let(:custom_properties) { {rate: '20'} } + describe '#call' do context 'without charge_model' do it 'returns empty hash' do @@ -90,6 +92,21 @@ let(:billable_metric) { build(:custom_billable_metric) } it { expect(filter_service.call.properties.keys).to include('custom_properties') } + it { expect(filter_service.call.properties[:custom_properties]).to be_a(Hash) } + + context 'when custom_properties is a string' do + let(:custom_properties) { '{"rate": 20}' } + + it { expect(filter_service.call.properties.keys).to include('custom_properties') } + it { expect(filter_service.call.properties[:custom_properties]).to eq('rate' => 20) } + + context 'when properties failed to parse' do + let(:custom_properties) { 'rate: 20' } + + it { expect(filter_service.call.properties.keys).to include('custom_properties') } + it { expect(filter_service.call.properties[:custom_properties]).to eq({}) } + end + end end end end