From 5c5a9a9920ab62b4a97551d4a78075d330a315d7 Mon Sep 17 00:00:00 2001 From: Vincent Pochet Date: Mon, 4 Nov 2024 12:01:30 +0100 Subject: [PATCH] feat(felixible aggregation): Expose expression in API (#223) * feat(felixible aggregation): Expose expression in API * feat(felixible aggregation): Add documentation for expression evaluation endpoint --- lib/lago/api/resources/billable_metric.rb | 23 +++++++++++++ spec/fixtures/api/billable_metric.json | 7 ++-- .../billable_metric_evaluate_expression.json | 5 +++ spec/fixtures/api/billable_metric_index.json | 2 ++ .../api/resources/billable_metric_spec.rb | 32 +++++++++++++++++++ 5 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 spec/fixtures/api/billable_metric_evaluate_expression.json diff --git a/lib/lago/api/resources/billable_metric.rb b/lib/lago/api/resources/billable_metric.rb index d17dd50..2885d6d 100644 --- a/lib/lago/api/resources/billable_metric.rb +++ b/lib/lago/api/resources/billable_metric.rb @@ -12,6 +12,15 @@ def root_name 'billable_metric' end + def evaluate_expression(params) + uri = URI("#{client.base_api_url}#{api_resource}/evaluate_expression") + + payload = whitelist_evalute_expression_params(params) + response = connection.post(payload, uri)['expression_result'] + + JSON.parse(response.to_json, object_class: OpenStruct) + end + def whitelist_params(params) { root_name => { @@ -22,10 +31,24 @@ def whitelist_params(params) aggregation_type: params[:aggregation_type], weighted_interval: params[:weighted_interval], field_name: params[:field_name], + expression: params[:expression], filters: params[:filters], }.compact, } end + + def whitelist_evalute_expression_params(params) + event = params[:event] || {} + + { + expression: params[:expression], + event: { + code: event[:code], + timestamp: event[:timestamp], + properties: event[:properties], + }.compact, + } + end end end end diff --git a/spec/fixtures/api/billable_metric.json b/spec/fixtures/api/billable_metric.json index f951bd4..a7ab7c4 100644 --- a/spec/fixtures/api/billable_metric.json +++ b/spec/fixtures/api/billable_metric.json @@ -7,16 +7,13 @@ "aggregation_type": "sum_agg", "weighted_interval": null, "recurring": false, + "expression": "1 + 2", "field_name": "amount_sum", "created_at": "2022-04-29T08:59:51Z", "filters": [ { "key": "country", - "values": [ - "france", - "italy", - "spain" - ] + "values": ["france", "italy", "spain"] } ], "active_subscriptions_count": 0, diff --git a/spec/fixtures/api/billable_metric_evaluate_expression.json b/spec/fixtures/api/billable_metric_evaluate_expression.json new file mode 100644 index 0000000..0f43e3c --- /dev/null +++ b/spec/fixtures/api/billable_metric_evaluate_expression.json @@ -0,0 +1,5 @@ +{ + "expression_result": { + "value": "2.0" + } +} diff --git a/spec/fixtures/api/billable_metric_index.json b/spec/fixtures/api/billable_metric_index.json index 4fc85f9..d17df3b 100644 --- a/spec/fixtures/api/billable_metric_index.json +++ b/spec/fixtures/api/billable_metric_index.json @@ -8,6 +8,7 @@ "aggregation_type": "sum_agg", "weighted_interval": null, "recurring": false, + "expression": "1 + 2", "field_name": "amount_sum", "created_at": "2022-04-29T08:59:51Z", "filters": [], @@ -23,6 +24,7 @@ "aggregation_type": "sum_agg", "weighted_interval": null, "recurring": false, + "expression": "1 + 2", "field_name": "amount_sum", "created_at": "2022-04-30T08:59:51Z", "filters": [], diff --git a/spec/lago/api/resources/billable_metric_spec.rb b/spec/lago/api/resources/billable_metric_spec.rb index b54f9af..987deaf 100644 --- a/spec/lago/api/resources/billable_metric_spec.rb +++ b/spec/lago/api/resources/billable_metric_spec.rb @@ -187,4 +187,36 @@ end end end + + describe '#evaluate_expression' do + let(:expression) { 'round(event.properties.value * event.properties.units)' } + let(:event) { { properties: { value: 10, units: 2 } } } + + let(:evaluate_expression_response) { load_fixture('billable_metric_evaluate_expression') } + + context 'when expression is successfully evaluated' do + before do + stub_request(:post, 'https://api.getlago.com/api/v1/billable_metrics/evaluate_expression') + .with(body: { expression: expression, event: event }) + .to_return(body: evaluate_expression_response, status: 200) + end + + it 'returns the evaluation result' do + evaluation_result = resource.evaluate_expression(event: event, expression: expression) + + expect(evaluation_result.value).to eq('2.0') + end + end + + context 'when there is an issue' do + before do + stub_request(:post, 'https://api.getlago.com/api/v1/billable_metrics/evaluate_expression') + .to_return(body: error_response, status: 422) + end + + it 'raises an error' do + expect { resource.evaluate_expression(event: event, expression: expression) }.to raise_error Lago::Api::HttpError + end + end + end end