From 894ca4040125da2f6b37d30031c1e35e5b1c18aa Mon Sep 17 00:00:00 2001 From: Vincent Pochet Date: Thu, 5 Sep 2024 15:37:19 +0200 Subject: [PATCH] feat(ProgressiveBilling): Expose lifetime usage GET and PUT (#212) --- lib/lago/api/resources/subscription.rb | 29 +++++++ spec/factories/lifetime_usage.rb | 7 ++ .../api/subscription_lifetime_usage.json | 24 ++++++ spec/lago/api/resources/subscription_spec.rb | 78 +++++++++++++++++++ 4 files changed, 138 insertions(+) create mode 100644 spec/factories/lifetime_usage.rb create mode 100644 spec/fixtures/api/subscription_lifetime_usage.json diff --git a/lib/lago/api/resources/subscription.rb b/lib/lago/api/resources/subscription.rb index 6fbc451..faf9732 100644 --- a/lib/lago/api/resources/subscription.rb +++ b/lib/lago/api/resources/subscription.rb @@ -12,6 +12,27 @@ def root_name 'subscription' end + def lifetime_usage(external_subscription_id) + uri = URI( + "#{client.base_api_url}#{api_resource}/#{external_subscription_id}/lifetime_usage", + ) + response = connection.get(uri, identifier: nil) + JSON.parse(response.to_json, object_class: OpenStruct).lifetime_usage + end + + def update_lifetime_usage(external_subscription_id, params) + uri = URI( + "#{client.base_api_url}#{api_resource}/#{external_subscription_id}/lifetime_usage", + ) + + response = connection.put( + uri, + identifier: nil, + body: whitelist_lifetime_usage_params(params), + ) + JSON.parse(response.to_json, object_class: OpenStruct).lifetime_usage + end + def whitelist_params(params) { root_name => { @@ -26,6 +47,14 @@ def whitelist_params(params) }.compact, } end + + def whitelist_lifetime_usage_params(params) + { + lifetime_usage: { + external_historical_usage_amount_cents: params[:external_historical_usage_amount_cents], + }, + } + end end end end diff --git a/spec/factories/lifetime_usage.rb b/spec/factories/lifetime_usage.rb new file mode 100644 index 0000000..c9bebd9 --- /dev/null +++ b/spec/factories/lifetime_usage.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :update_lifetime_usage, class: OpenStruct do + external_historical_usage_amount_cents { 100 } + end +end diff --git a/spec/fixtures/api/subscription_lifetime_usage.json b/spec/fixtures/api/subscription_lifetime_usage.json new file mode 100644 index 0000000..b5c4f22 --- /dev/null +++ b/spec/fixtures/api/subscription_lifetime_usage.json @@ -0,0 +1,24 @@ +{ + "lifetime_usage": { + "lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "lago_subscription_id": "1a901a90-1a90-1a90-1a90-1a901a901a90", + "external_subscription_id": "sub-12345", + "external_historical_usage_amount_cents": 20, + "invoiced_usage_amount_cents": 2000, + "current_usage_amount_cents": 100, + "from_datetime": "2022-04-29T08:59:51Z", + "to_datetime": "2024-02-10T08:59:51Z", + "usage_thresholds": [ + { + "amount_cents": 100, + "completion_ratio": 1.0, + "reached_at": "2024-01-09T08:59:51Z" + }, + { + "amount_cents": 3000, + "completion_ratio": "0.6733333", + "reached_at": null + } + ] + } +} diff --git a/spec/lago/api/resources/subscription_spec.rb b/spec/lago/api/resources/subscription_spec.rb index 501a37e..1ae3007 100644 --- a/spec/lago/api/resources/subscription_spec.rb +++ b/spec/lago/api/resources/subscription_spec.rb @@ -247,4 +247,82 @@ end end end + + describe '#lifetime_usage' do + let(:json_response) { load_fixture('subscription_lifetime_usage') } + let(:lifetime_usage_response) { JSON.parse(json_response) } + let(:external_subscription_id) { lifetime_usage_response['lifetime_usage']['external_subscription_id'] } + + context 'when lifetime usage is successfully retrieved' do + before do + stub_request(:get, "https://api.getlago.com/api/v1/subscriptions/#{external_subscription_id}/lifetime_usage") + .to_return(body: json_response, status: 200) + end + + it 'returns lifetime usage' do + lifetime_usage = resource.lifetime_usage(external_subscription_id) + + expect(lifetime_usage.external_subscription_id).to eq(external_subscription_id) + end + end + + context 'when lifetime usage is not found' do + let(:not_found_response) do + { + 'status' => 404, + 'error' => 'Not Found', + 'code' => 'credit_note_not_found', + }.to_json + end + + before do + stub_request(:get, "https://api.getlago.com/api/v1/subscriptions/#{external_subscription_id}/lifetime_usage") + .to_return(body: not_found_response, status: 404) + end + + it 'raises an error' do + expect { resource.lifetime_usage(external_subscription_id) }.to raise_error(Lago::Api::HttpError) + end + end + end + + describe '#update_lifetime_usage' do + let(:params) { create(:update_lifetime_usage).to_h } + + let(:json_response) { load_fixture('subscription_lifetime_usage') } + let(:lifetime_usage_response) { JSON.parse(json_response) } + let(:external_subscription_id) { lifetime_usage_response['lifetime_usage']['external_subscription_id'] } + + before do + stub_request(:put, "https://api.getlago.com/api/v1/subscriptions/#{external_subscription_id}/lifetime_usage") + .with(body: { lifetime_usage: params }) + .to_return(body: json_response, status: 200) + end + + it 'returns lifetime usage' do + lifetime_usage = resource.update_lifetime_usage(external_subscription_id, params) + + expect(lifetime_usage.external_subscription_id).to eq(external_subscription_id) + end + + context 'when lifetime usage is not found' do + let(:not_found_response) do + { + 'status' => 404, + 'error' => 'Not Found', + 'code' => 'credit_note_not_found', + }.to_json + end + + before do + stub_request(:put, "https://api.getlago.com/api/v1/subscriptions/#{external_subscription_id}/lifetime_usage") + .with(body: { lifetime_usage: params }) + .to_return(body: not_found_response, status: 404) + end + + it 'raises an error' do + expect { resource.update_lifetime_usage(external_subscription_id, params) }.to raise_error(Lago::Api::HttpError) + end + end + end end