From f7906d5d772ec20859f9720d7277de9604e69446 Mon Sep 17 00:00:00 2001 From: Vincent Pochet Date: Mon, 2 Oct 2023 10:21:39 +0200 Subject: [PATCH] feat(past_usage): Expose route to fetch customer past usage --- lib/lago/api/resources/customer.rb | 16 +++++- spec/fixtures/api/customer_past_usage.json | 39 ++++++++++++++ spec/fixtures/api/customer_usage.json | 2 + spec/lago/api/resources/customer_spec.rb | 61 ++++++++++++++++++++++ 4 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 spec/fixtures/api/customer_past_usage.json diff --git a/lib/lago/api/resources/customer.rb b/lib/lago/api/resources/customer.rb index be03ec9..c1b17b4 100644 --- a/lib/lago/api/resources/customer.rb +++ b/lib/lago/api/resources/customer.rb @@ -14,14 +14,26 @@ def root_name def current_usage(external_customer_id, external_subscription_id) uri = URI( - "#{client.base_api_url}#{api_resource}/#{external_customer_id}/current_usage?external_subscription_id=#{external_subscription_id}" + "#{client.base_api_url}#{api_resource}/#{external_customer_id}" \ + "/current_usage?external_subscription_id=#{external_subscription_id}", ) connection.get(uri, identifier: nil) end + def past_usage(external_customer_id, external_subscription_id, options = {}) + uri = URI( + "#{client.base_api_url}#{api_resource}/#{external_customer_id}/past_usage", + ) + + connection.get_all( + options.merge(external_subscription_id: external_subscription_id), + uri, + ) + end + def portal_url(external_customer_id) uri = URI( - "#{client.base_api_url}#{api_resource}/#{external_customer_id}/portal_url" + "#{client.base_api_url}#{api_resource}/#{external_customer_id}/portal_url", ) response = connection.get(uri, identifier: nil)[root_name] diff --git a/spec/fixtures/api/customer_past_usage.json b/spec/fixtures/api/customer_past_usage.json new file mode 100644 index 0000000..7aae8f3 --- /dev/null +++ b/spec/fixtures/api/customer_past_usage.json @@ -0,0 +1,39 @@ +{ + "usage_periods": [ + { + "from_datetime": "2022-07-01T00:00:00Z", + "to_datetime": "2022-07-31T23:59:59Z", + "issuing_date": "2022-08-01", + "lago_invoice_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "currency": "EUR", + "amount_cents": 123, + "total_amount_cents": 123, + "taxes_amount_cents": 0, + "charges_usage": [ + { + "units": "1.0", + "events_count": 1, + "amount_cents": 123, + "amount_currency": "EUR", + "charge": { + "lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "charge_model": "graduated" + }, + "billable_metric": { + "lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "name": "Usage metric", + "code": "usage_metric", + "aggregation_type": "sum" + } + } + ] + } + ], + "meta": { + "current_page": 1, + "next_page": 2, + "prev_page": null, + "total_pages": 2, + "total_count": 49 + } +} diff --git a/spec/fixtures/api/customer_usage.json b/spec/fixtures/api/customer_usage.json index 6ede85b..23e34f7 100644 --- a/spec/fixtures/api/customer_usage.json +++ b/spec/fixtures/api/customer_usage.json @@ -3,6 +3,7 @@ "from_datetime": "2022-07-01T00:00:00Z", "to_datetime": "2022-07-31T23:59:59Z", "issuing_date": "2022-08-01", + "lago_invoice_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", "currency": "EUR", "amount_cents": 123, "total_amount_cents": 123, @@ -10,6 +11,7 @@ "charges_usage": [ { "units": "1.0", + "events_count": 1, "amount_cents": 123, "amount_currency": "EUR", "charge": { diff --git a/spec/lago/api/resources/customer_spec.rb b/spec/lago/api/resources/customer_spec.rb index ec856f5..7f0b840 100644 --- a/spec/lago/api/resources/customer_spec.rb +++ b/spec/lago/api/resources/customer_spec.rb @@ -112,6 +112,67 @@ end end + describe '#past_usage' do + let(:customer_usage_response) { load_fixture('customer_past_usage') } + let(:subscription_external_id) { '123' } + + context 'when the customer exists' do + before do + stub_request(:get, "https://api.getlago.com/api/v1/customers/#{customer_external_id}/past_usage?external_subscription_id=#{subscription_external_id}") + .to_return(body: customer_usage_response, status: 200) + end + + it 'returns the past usage of the customer' do + response = resource.past_usage(customer_external_id, subscription_external_id) + + expect(response['usage_periods'].count).to eq(1) + expect(response['usage_periods'].first['from_datetime']).to eq('2022-07-01T00:00:00Z') + end + end + + context 'with a filter on a billable metric code' do + before do + stub_request(:get, "https://api.getlago.com/api/v1/customers/#{customer_external_id}/past_usage?external_subscription_id=#{subscription_external_id}&billable_metric_code=bm_code") + .to_return(body: customer_usage_response, status: 200) + end + + it 'returns the past usage of the customer' do + response = resource.past_usage(customer_external_id, subscription_external_id, billable_metric_code: 'bm_code') + + expect(response['usage_periods'].count).to eq(1) + expect(response['usage_periods'].first['from_datetime']).to eq('2022-07-01T00:00:00Z') + end + end + + context 'when the customer does not exists' do + let(:customer_external_id) { 'DOESNOTEXIST' } + + before do + stub_request(:get, "https://api.getlago.com/api/v1/customers/#{customer_external_id}/past_usage?external_subscription_id=#{subscription_external_id}") + .to_return(body: JSON.generate(status: 404, error: 'Not Found'), status: 404) + end + + it 'raises an error' do + expect do + resource.past_usage(customer_external_id, subscription_external_id) + end.to raise_error(Lago::Api::HttpError) + end + end + + context 'when the customer does not have a subscription' do + before do + stub_request(:get, "https://api.getlago.com/api/v1/customers/#{customer_external_id}/past_usage?external_subscription_id=#{subscription_external_id}") + .to_return(body: JSON.generate(status: 422, error: 'no_active_subscription'), status: 422) + end + + it 'raises an error' do + expect do + resource.past_usage(customer_external_id, subscription_external_id) + end.to raise_error(Lago::Api::HttpError) + end + end + end + describe '#plan_url' do context 'when the customer exists' do before do