From abc76280295408d6977cf681143e0886b8d8f605 Mon Sep 17 00:00:00 2001 From: Stanislav Kolotinskiy Date: Tue, 10 Aug 2021 17:42:21 +0300 Subject: [PATCH 01/20] Implement v2 cancellations --- lib/travis/api/v3/billing_client.rb | 5 +++ lib/travis/api/v3/queries/v2_subscription.rb | 6 +++ lib/travis/api/v3/routes.rb | 1 + .../api/v3/services/v2_subscription/cancel.rb | 11 ++++++ spec/v3/billing_client_spec.rb | 13 +++++++ .../services/v2_subscription/cancel_spec.rb | 39 +++++++++++++++++++ 6 files changed, 75 insertions(+) create mode 100644 lib/travis/api/v3/services/v2_subscription/cancel.rb create mode 100644 spec/v3/services/v2_subscription/cancel_spec.rb diff --git a/lib/travis/api/v3/billing_client.rb b/lib/travis/api/v3/billing_client.rb index a1db814173..3d28e463a5 100644 --- a/lib/travis/api/v3/billing_client.rb +++ b/lib/travis/api/v3/billing_client.rb @@ -215,6 +215,11 @@ def get_auto_refill(plan_id) handle_errors_and_respond(response) { |r| Travis::API::V3::Models::AutoRefill.new(r) } end + def cancel_v2_subscription(id, reason_data) + response = connection.post("/v2/subscriptions/#{id}/cancel", reason_data) + handle_subscription_response(response) + end + private def handle_subscription_response(response) diff --git a/lib/travis/api/v3/queries/v2_subscription.rb b/lib/travis/api/v3/queries/v2_subscription.rb index 2aef83390d..0b7cc6a8fd 100644 --- a/lib/travis/api/v3/queries/v2_subscription.rb +++ b/lib/travis/api/v3/queries/v2_subscription.rb @@ -49,5 +49,11 @@ def toggle_auto_refill(user_id, plan_id) client = BillingClient.new(user_id) client.create_auto_refill(plan_id, enabled) end + + def cancel(user_id) + reason_data = params.dup.tap { |h| h.delete('subscription.id') } + client = BillingClient.new(user_id) + client.cancel_v2_subscription(params['subscription.id'], reason_data) + end end end diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index 1826d80455..834e41589e 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -364,6 +364,7 @@ module Routes patch :changetofree, '/changetofree' patch :update_plan, '/plan' post :pay, '/pay' + post :cancel, '/cancel' post :buy_addon, '/addon/{addon.id}' get :user_usages, '/user_usages' get :invoices, '/invoices' diff --git a/lib/travis/api/v3/services/v2_subscription/cancel.rb b/lib/travis/api/v3/services/v2_subscription/cancel.rb new file mode 100644 index 0000000000..9ef5481b79 --- /dev/null +++ b/lib/travis/api/v3/services/v2_subscription/cancel.rb @@ -0,0 +1,11 @@ +module Travis::API::V3 + class Services::V2Subscription::Cancel < Service + params :reason, :reason_details + + def run! + raise LoginRequired unless access_control.full_access_or_logged_in? + query.cancel(access_control.user.id) + no_content + end + end +end diff --git a/spec/v3/billing_client_spec.rb b/spec/v3/billing_client_spec.rb index 55684816d8..304e6e8a8b 100644 --- a/spec/v3/billing_client_spec.rb +++ b/spec/v3/billing_client_spec.rb @@ -433,4 +433,17 @@ expect(subject.first.os).to eq 'linux' end end + + describe '#cancel_v2_subscription' do + let(:reason_data) { { 'reason' => 'Other', 'reason_details' => 'Cancellation details go here' } } + subject { billing.cancel_v2_subscription(subscription_id, reason_data) } + + it 'requests the cancelation of a subscription' do + stubbed_request = stub_billing_request(:post, "/v2/subscriptions/#{subscription_id}/cancel", auth_key: auth_key, user_id: user_id) + .to_return(status: 204) + + expect { subject }.to_not raise_error + expect(stubbed_request).to have_been_made + end + end end diff --git a/spec/v3/services/v2_subscription/cancel_spec.rb b/spec/v3/services/v2_subscription/cancel_spec.rb new file mode 100644 index 0000000000..9f8f839551 --- /dev/null +++ b/spec/v3/services/v2_subscription/cancel_spec.rb @@ -0,0 +1,39 @@ +describe Travis::API::V3::Services::V2Subscription::Cancel, set_app: true, billing_spec_helper: true do + let(:billing_url) { 'http://billingfake.travis-ci.com' } + let(:billing_auth_key) { 'secret' } + let(:reason_data) { { 'reason' => 'Other', 'reason_details' => 'Cancellation details go here' } } + + before do + Travis.config.billing.url = billing_url + Travis.config.billing.auth_key = billing_auth_key + end + + context 'unauthenticated' do + it 'responds 403' do + post('/v3/v2_subscription/123/cancel', {}) + + expect(last_response.status).to eq(403) + end + end + + context 'authenticated' do + let(:user) { FactoryBot.create(:user) } + let(:token) { Travis::Api::App::AccessToken.create(user: user, app_id: 1) } + let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}", + 'CONTENT_TYPE' => 'application/json' }} + let(:subscription_id) { rand(999) } + + let!(:stubbed_request) do + stub_billing_request(:post, "/v2/subscriptions/#{subscription_id}/cancel", auth_key: billing_auth_key, user_id: user.id) + .with(body: reason_data) + .to_return(status: 204) + end + + it 'cancels the subscription' do + post("/v3/v2_subscription/#{subscription_id}/cancel", JSON.generate(reason_data), headers) + + expect(last_response.status).to eq(204) + expect(stubbed_request).to have_been_made.once + end + end +end From d6d4908ec87f235dacd39945580d1c3366e71d87 Mon Sep 17 00:00:00 2001 From: AndriiMysko Date: Tue, 17 Aug 2021 15:58:24 +0300 Subject: [PATCH 02/20] Update API for new plans --- lib/travis/api/v3/models/v2_addon.rb | 3 ++- lib/travis/api/v3/models/v2_plan_config.rb | 4 +++- lib/travis/api/v3/models/v2_subscription.rb | 3 ++- lib/travis/api/v3/renderer/v2_addon.rb | 4 ++-- lib/travis/api/v3/renderer/v2_plan_config.rb | 4 ++-- lib/travis/api/v3/renderer/v2_subscription.rb | 2 +- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/travis/api/v3/models/v2_addon.rb b/lib/travis/api/v3/models/v2_addon.rb index 74de457e13..dfd86c2491 100644 --- a/lib/travis/api/v3/models/v2_addon.rb +++ b/lib/travis/api/v3/models/v2_addon.rb @@ -1,12 +1,13 @@ module Travis::API::V3 class Models::V2Addon - attr_reader :id, :name, :type, :current_usage + attr_reader :id, :name, :type, :current_usage, :recurring def initialize(attrs) @id = attrs.fetch('id') @name = attrs.fetch('name') @type = attrs.fetch('type') @current_usage = attrs['current_usage'] && Models::V2AddonUsage.new(attrs['current_usage']) + @recurring = attrs['recurring'] end end end diff --git a/lib/travis/api/v3/models/v2_plan_config.rb b/lib/travis/api/v3/models/v2_plan_config.rb index 7baa09cba1..18a5249b2a 100644 --- a/lib/travis/api/v3/models/v2_plan_config.rb +++ b/lib/travis/api/v3/models/v2_plan_config.rb @@ -1,7 +1,8 @@ module Travis::API::V3 class Models::V2PlanConfig attr_reader :id, :name, :private_repos, :starting_price, :starting_users, :plan_type, - :private_credits, :public_credits, :addon_configs, :concurrency_limit, :available_standalone_addons, :auto_refill_enabled + :private_credits, :public_credits, :addon_configs, :concurrency_limit, :available_standalone_addons, :auto_refill_enabled, + :annual def initialize(attrs) @id = attrs.fetch('id') @@ -15,6 +16,7 @@ def initialize(attrs) @plan_type = attrs.fetch('plan_type') @concurrency_limit = attrs.fetch('concurrency_limit') @available_standalone_addons = attrs.fetch('available_standalone_addons') + @annual = attrs.fetch('annual') end end end diff --git a/lib/travis/api/v3/models/v2_subscription.rb b/lib/travis/api/v3/models/v2_subscription.rb index 91174050ab..522a9b3961 100644 --- a/lib/travis/api/v3/models/v2_subscription.rb +++ b/lib/travis/api/v3/models/v2_subscription.rb @@ -3,7 +3,7 @@ class Models::V2Subscription include Models::Owner attr_reader :id, :plan, :permissions, :source, :billing_info, :credit_card_info, :owner, :status, :valid_to, :canceled_at, - :client_secret, :payment_intent, :addons, :auto_refill, :available_standalone_addons, :created_at + :client_secret, :payment_intent, :addons, :auto_refill, :available_standalone_addons, :created_at, :scheduled_plan_name def initialize(attributes = {}) @id = attributes.fetch('id') @@ -30,6 +30,7 @@ def initialize(attributes = {}) @status = attributes.fetch('status') @valid_to = attributes.fetch('valid_to') @canceled_at = attributes.fetch('canceled_at') + @scheduled_plan_name = attributes.fetch('scheduled_plan') end end diff --git a/lib/travis/api/v3/renderer/v2_addon.rb b/lib/travis/api/v3/renderer/v2_addon.rb index 9e6410c6ce..8b3a39c3ca 100644 --- a/lib/travis/api/v3/renderer/v2_addon.rb +++ b/lib/travis/api/v3/renderer/v2_addon.rb @@ -1,7 +1,7 @@ module Travis::API::V3 class Renderer::V2Addon < ModelRenderer - representation(:standard, :id, :name, :type, :current_usage) - representation(:minimal, :id, :name, :type, :current_usage) + representation(:standard, :id, :name, :type, :current_usage, :recurring) + representation(:minimal, :id, :name, :type, :current_usage, :recurring) def current_usage Renderer.render_model(model.current_usage, mode: :standard) unless model.current_usage.nil? diff --git a/lib/travis/api/v3/renderer/v2_plan_config.rb b/lib/travis/api/v3/renderer/v2_plan_config.rb index c95a156fb3..d4306f8f06 100644 --- a/lib/travis/api/v3/renderer/v2_plan_config.rb +++ b/lib/travis/api/v3/renderer/v2_plan_config.rb @@ -1,8 +1,8 @@ module Travis::API::V3 class Renderer::V2PlanConfig < ModelRenderer representation(:standard, :id, :name, :private_repos, :starting_price, :starting_users, :private_credits, - :public_credits, :addon_configs, :plan_type, :concurrency_limit, :available_standalone_addons) + :public_credits, :addon_configs, :plan_type, :concurrency_limit, :available_standalone_addons, :annual) representation(:minimal, :id, :name, :private_repos, :starting_price, :starting_users, :private_credits, - :public_credits, :addon_configs, :plan_type, :concurrency_limit) + :public_credits, :addon_configs, :plan_type, :concurrency_limit, :annual) end end diff --git a/lib/travis/api/v3/renderer/v2_subscription.rb b/lib/travis/api/v3/renderer/v2_subscription.rb index daeb54912d..4a6f677331 100644 --- a/lib/travis/api/v3/renderer/v2_subscription.rb +++ b/lib/travis/api/v3/renderer/v2_subscription.rb @@ -1,6 +1,6 @@ module Travis::API::V3 class Renderer::V2Subscription < ModelRenderer - representation(:standard, :id, :plan, :addons, :auto_refill, :status, :valid_to, :canceled_at, :source, :owner, :client_secret, :billing_info, :credit_card_info, :payment_intent, :created_at) + representation(:standard, :id, :plan, :addons, :auto_refill, :status, :valid_to, :canceled_at, :source, :owner, :client_secret, :billing_info, :credit_card_info, :payment_intent, :created_at, :scheduled_plan_name) def billing_info Renderer.render_model(model.billing_info, mode: :standard) unless model.billing_info.nil? From edcb43a40a34359c7d08048795c32d9372f1a217 Mon Sep 17 00:00:00 2001 From: AndriiMysko Date: Fri, 20 Aug 2021 17:11:33 +0300 Subject: [PATCH 03/20] Auto refill modifications WIP --- lib/travis/api/v3/billing_client.rb | 5 +++++ lib/travis/api/v3/models/auto_refill.rb | 3 ++- lib/travis/api/v3/models/v2_plan_config.rb | 4 +++- lib/travis/api/v3/queries/v2_subscription.rb | 7 ++++++- lib/travis/api/v3/renderer/auto_refill.rb | 4 ++-- lib/travis/api/v3/renderer/v2_plan_config.rb | 4 ++-- lib/travis/api/v3/routes.rb | 1 + .../v3/services/v2_subscription/update_auto_refill.rb | 10 ++++++++++ 8 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 lib/travis/api/v3/services/v2_subscription/update_auto_refill.rb diff --git a/lib/travis/api/v3/billing_client.rb b/lib/travis/api/v3/billing_client.rb index a1db814173..0595ecbc9f 100644 --- a/lib/travis/api/v3/billing_client.rb +++ b/lib/travis/api/v3/billing_client.rb @@ -210,6 +210,11 @@ def create_auto_refill(plan_id, is_enabled) handle_errors_and_respond(response) end + def update_auto_refill(addon_id, threshold, amount) + response = connection.patch('/auto_refill', {id: addon_id, threshold: threshold, amount: amount}) + handle_errors_and_respond(response) + end + def get_auto_refill(plan_id) response = connection.get("/auto_refill?plan_id=#{plan_id}") handle_errors_and_respond(response) { |r| Travis::API::V3::Models::AutoRefill.new(r) } diff --git a/lib/travis/api/v3/models/auto_refill.rb b/lib/travis/api/v3/models/auto_refill.rb index 60fcac406e..1685a6ec84 100644 --- a/lib/travis/api/v3/models/auto_refill.rb +++ b/lib/travis/api/v3/models/auto_refill.rb @@ -1,8 +1,9 @@ module Travis::API::V3 class Models::AutoRefill - attr_reader :enabled, :threshold, :amount + attr_reader :addon_id, :enabled, :threshold, :amount def initialize(attributes = {}) + @addon_id = attributes.fetch('addon_id', nil) || attributes.fetch('id', nil) @enabled = attributes.key?('enabled') ? attributes.fetch('enabled') : true @threshold = attributes.key?('refill_threshold') ? attributes.fetch('refill_threshold') : 25000 @amount = attributes.key?('refill_amount') ? attributes.fetch('refill_amount'): 10000 diff --git a/lib/travis/api/v3/models/v2_plan_config.rb b/lib/travis/api/v3/models/v2_plan_config.rb index 18a5249b2a..2cd12a143d 100644 --- a/lib/travis/api/v3/models/v2_plan_config.rb +++ b/lib/travis/api/v3/models/v2_plan_config.rb @@ -2,7 +2,7 @@ module Travis::API::V3 class Models::V2PlanConfig attr_reader :id, :name, :private_repos, :starting_price, :starting_users, :plan_type, :private_credits, :public_credits, :addon_configs, :concurrency_limit, :available_standalone_addons, :auto_refill_enabled, - :annual + :annual, :auto_refill_thresholds, :auto_refill_amounts def initialize(attrs) @id = attrs.fetch('id') @@ -17,6 +17,8 @@ def initialize(attrs) @concurrency_limit = attrs.fetch('concurrency_limit') @available_standalone_addons = attrs.fetch('available_standalone_addons') @annual = attrs.fetch('annual') + @auto_refill_thresholds = attrs.fetch('auto_refill_thresholds') + @auto_refill_amounts = attrs.fetch('auto_refill_amounts') end end end diff --git a/lib/travis/api/v3/queries/v2_subscription.rb b/lib/travis/api/v3/queries/v2_subscription.rb index 2aef83390d..0fac4d3a84 100644 --- a/lib/travis/api/v3/queries/v2_subscription.rb +++ b/lib/travis/api/v3/queries/v2_subscription.rb @@ -1,6 +1,6 @@ module Travis::API::V3 class Queries::V2Subscription < Query - params :enabled + params :enabled, :threshold, :amount def update_address(user_id) address_data = params.dup.tap { |h| h.delete('subscription.id') } @@ -49,5 +49,10 @@ def toggle_auto_refill(user_id, plan_id) client = BillingClient.new(user_id) client.create_auto_refill(plan_id, enabled) end + + def update_auto_refill(user_id, addon_id) + client = BillingClient.new(user_id) + client.update_auto_refill(addon_id, threshold, amount) + end end end diff --git a/lib/travis/api/v3/renderer/auto_refill.rb b/lib/travis/api/v3/renderer/auto_refill.rb index d85fe95bfd..fb9b41298b 100644 --- a/lib/travis/api/v3/renderer/auto_refill.rb +++ b/lib/travis/api/v3/renderer/auto_refill.rb @@ -1,6 +1,6 @@ module Travis::API::V3 class Renderer::AutoRefill < ModelRenderer - representation(:standard, :enabled, :threshold, :amount) - representation(:minimal, :enabled, :threshold, :amount) + representation(:standard, :addon_id, :enabled, :threshold, :amount) + representation(:minimal, :addon_id, :enabled, :threshold, :amount) end end diff --git a/lib/travis/api/v3/renderer/v2_plan_config.rb b/lib/travis/api/v3/renderer/v2_plan_config.rb index d4306f8f06..cacf97bee9 100644 --- a/lib/travis/api/v3/renderer/v2_plan_config.rb +++ b/lib/travis/api/v3/renderer/v2_plan_config.rb @@ -1,8 +1,8 @@ module Travis::API::V3 class Renderer::V2PlanConfig < ModelRenderer representation(:standard, :id, :name, :private_repos, :starting_price, :starting_users, :private_credits, - :public_credits, :addon_configs, :plan_type, :concurrency_limit, :available_standalone_addons, :annual) + :public_credits, :addon_configs, :plan_type, :concurrency_limit, :available_standalone_addons, :annual, :auto_refill_thresholds, :auto_refill_amounts) representation(:minimal, :id, :name, :private_repos, :starting_price, :starting_users, :private_credits, - :public_credits, :addon_configs, :plan_type, :concurrency_limit, :annual) + :public_credits, :addon_configs, :plan_type, :concurrency_limit, :annual, :auto_refill_thresholds, :auto_refill_amounts) end end diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index 1826d80455..20f13f651a 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -369,6 +369,7 @@ module Routes get :invoices, '/invoices' get :auto_refill, '/auto_refill' patch :toggle_auto_refill, '/auto_refill' + patch :update_auto_refill, '/update_auto_refill' end hidden_resource :trials do diff --git a/lib/travis/api/v3/services/v2_subscription/update_auto_refill.rb b/lib/travis/api/v3/services/v2_subscription/update_auto_refill.rb new file mode 100644 index 0000000000..377b3ea0b8 --- /dev/null +++ b/lib/travis/api/v3/services/v2_subscription/update_auto_refill.rb @@ -0,0 +1,10 @@ +module Travis::API::V3 + class Services::V2Subscription::UpdateAutoRefill < Service + params :addon_id, :threshold, :amount + def run! + raise LoginRequired unless access_control.full_access_or_logged_in? + query.update_auto_refill(access_control.user.id, params['addon_id']) + no_content + end + end +end From 04eacba8e6c9d9eb1d3dcd751ec8b67dd4178797 Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Mon, 30 Aug 2021 11:04:57 +0300 Subject: [PATCH 04/20] Fix spec --- spec/v3/services/v2_subscriptions/create_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/v3/services/v2_subscriptions/create_spec.rb b/spec/v3/services/v2_subscriptions/create_spec.rb index 6e9a33a621..44ef6abffb 100644 --- a/spec/v3/services/v2_subscriptions/create_spec.rb +++ b/spec/v3/services/v2_subscriptions/create_spec.rb @@ -82,6 +82,7 @@ 'starting_users' => 10_000, 'private_credits' => 500_000, 'public_credits' => 40_000, + 'annual' => false, 'available_standalone_addons' => [ { 'id' => 'credits_25k', From d3418401b2adbd9baac1c67b262c563eb06b764a Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Mon, 30 Aug 2021 11:11:44 +0300 Subject: [PATCH 05/20] Fix spec --- spec/v3/services/v2_subscriptions/create_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/v3/services/v2_subscriptions/create_spec.rb b/spec/v3/services/v2_subscriptions/create_spec.rb index 44ef6abffb..05a8bfc7d8 100644 --- a/spec/v3/services/v2_subscriptions/create_spec.rb +++ b/spec/v3/services/v2_subscriptions/create_spec.rb @@ -83,6 +83,7 @@ 'private_credits' => 500_000, 'public_credits' => 40_000, 'annual' => false, + 'scheduled_plan' => '', 'available_standalone_addons' => [ { 'id' => 'credits_25k', From 043d9391fc4f0126bfc9a7d78bee7c6f618fde72 Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Mon, 30 Aug 2021 11:17:58 +0300 Subject: [PATCH 06/20] Fix spec --- spec/v3/services/v2_subscriptions/create_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/v3/services/v2_subscriptions/create_spec.rb b/spec/v3/services/v2_subscriptions/create_spec.rb index 05a8bfc7d8..26401ff993 100644 --- a/spec/v3/services/v2_subscriptions/create_spec.rb +++ b/spec/v3/services/v2_subscriptions/create_spec.rb @@ -72,6 +72,7 @@ 'canceled_at': nil, 'valid_to': nil, 'status': nil, + 'scheduled_plan': nil, 'plan_config' => { 'id' => 'pro_tier_plan', 'name' => 'Pro Tier Plan', @@ -83,7 +84,6 @@ 'private_credits' => 500_000, 'public_credits' => 40_000, 'annual' => false, - 'scheduled_plan' => '', 'available_standalone_addons' => [ { 'id' => 'credits_25k', From c5fa345b3d697cdd60dcae568b11db0d7c9dc91f Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Mon, 30 Aug 2021 11:27:01 +0300 Subject: [PATCH 07/20] Fix spec --- spec/v3/services/v2_subscriptions/create_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/v3/services/v2_subscriptions/create_spec.rb b/spec/v3/services/v2_subscriptions/create_spec.rb index 26401ff993..d709222758 100644 --- a/spec/v3/services/v2_subscriptions/create_spec.rb +++ b/spec/v3/services/v2_subscriptions/create_spec.rb @@ -188,6 +188,7 @@ 'canceled_at' => nil, 'status' => nil, 'valid_to' => nil, + 'scheduled_plan' => nil, 'plan' => { '@type' => 'v2_plan_config', '@representation' => 'standard', @@ -200,6 +201,7 @@ 'public_credits' => 40_000, 'concurrency_limit' => 20, 'plan_type' => 'metered', + 'annual' => false, 'available_standalone_addons' => [ { 'id' => 'credits_25k', @@ -259,6 +261,7 @@ 'id' => 7, 'name' => 'OSS Build Credits', 'type' => 'credit_public', + 'recurring' => nil, 'current_usage' => { '@type' => 'v2_addon_usage', '@representation' => 'standard', From 2b6bb842b3aa7ca0389f5e88f9ee0958915d621a Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Mon, 30 Aug 2021 11:33:13 +0300 Subject: [PATCH 08/20] Fix spec --- spec/v3/services/v2_subscriptions/create_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/v3/services/v2_subscriptions/create_spec.rb b/spec/v3/services/v2_subscriptions/create_spec.rb index d709222758..4733f933c7 100644 --- a/spec/v3/services/v2_subscriptions/create_spec.rb +++ b/spec/v3/services/v2_subscriptions/create_spec.rb @@ -188,7 +188,7 @@ 'canceled_at' => nil, 'status' => nil, 'valid_to' => nil, - 'scheduled_plan' => nil, + 'scheduled_plan_name' => nil, 'plan' => { '@type' => 'v2_plan_config', '@representation' => 'standard', From 0a861c59671aa7f80d4195c1c50e0fc0357efea1 Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Mon, 30 Aug 2021 11:44:43 +0300 Subject: [PATCH 09/20] Fix spec --- spec/support/billing_spec_helper.rb | 4 ++++ spec/v3/services/v2_subscriptions/all_spec.rb | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/spec/support/billing_spec_helper.rb b/spec/support/billing_spec_helper.rb index f7e368a10f..fd1ebc0535 100644 --- a/spec/support/billing_spec_helper.rb +++ b/spec/support/billing_spec_helper.rb @@ -51,6 +51,7 @@ def billing_v2_subscription_response_body(attributes={}) 'status' => nil, 'valid_to' => nil, 'canceled_at' => nil, + "scheduled_plan" => nil, "plan_config" => { 'id' => 'pro_tier_plan', 'name' => 'Pro Tier Plan', @@ -61,6 +62,7 @@ def billing_v2_subscription_response_body(attributes={}) 'starting_users' => 10000, 'private_credits' => 500000, 'public_credits' => 40000, + 'annual' => false, 'available_standalone_addons' => [ { 'id' => 'credits_25k', @@ -141,6 +143,7 @@ def billing_addons_response_body "id" => "1", "name" => "OSS Build Credits", "type" => "credit_public", + "recurring" => false, "current_usage" => { "id" => 1, "addon_id" => 1, @@ -157,6 +160,7 @@ def billing_addons_response_body "id" => 2, "name" => "Build Credits", "type" => "credit_private", + "recurring" => false, "current_usage" => { "id" => 2, "addon_id" => 2, diff --git a/spec/v3/services/v2_subscriptions/all_spec.rb b/spec/v3/services/v2_subscriptions/all_spec.rb index 4b5859dbdd..b2ed5637b6 100644 --- a/spec/v3/services/v2_subscriptions/all_spec.rb +++ b/spec/v3/services/v2_subscriptions/all_spec.rb @@ -82,6 +82,7 @@ 'canceled_at' => nil, 'status' => nil, 'valid_to' => nil, + 'scheduled_plan' => nil, 'plan' => { '@type' => 'v2_plan_config', '@representation' => 'standard', @@ -94,6 +95,7 @@ 'starting_users' => 10_000, 'private_credits' => 500_000, 'public_credits' => 40_000, + 'annual' => false, 'available_standalone_addons' => [ { 'id' => 'credits_25k', @@ -154,6 +156,7 @@ 'id' => '1', 'name' => 'OSS Build Credits', 'type' => 'credit_public', + 'recurring' => false, 'current_usage' => { '@type' => 'v2_addon_usage', '@representation' => 'standard', @@ -174,6 +177,7 @@ 'id' => 2, 'name' => 'Build Credits', 'type' => 'credit_private', + 'recurring' => false, 'current_usage' => { '@type' => 'v2_addon_usage', From 9300aa4fba5f44c0670de80824079b5595d27741 Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Mon, 30 Aug 2021 11:55:35 +0300 Subject: [PATCH 10/20] Fix spec --- spec/support/billing_spec_helper.rb | 1 + spec/v3/services/v2_subscriptions/all_spec.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/support/billing_spec_helper.rb b/spec/support/billing_spec_helper.rb index fd1ebc0535..74395d77db 100644 --- a/spec/support/billing_spec_helper.rb +++ b/spec/support/billing_spec_helper.rb @@ -237,6 +237,7 @@ def billing_v2_plan_response_body(attributes = {}) 'starting_users' => 999_999, 'private_credits' => 10_000, 'public_credits' => 40_000, + 'annual' => false, 'available_standalone_addons' => [] }.deep_merge(attributes) end diff --git a/spec/v3/services/v2_subscriptions/all_spec.rb b/spec/v3/services/v2_subscriptions/all_spec.rb index b2ed5637b6..6820dc9414 100644 --- a/spec/v3/services/v2_subscriptions/all_spec.rb +++ b/spec/v3/services/v2_subscriptions/all_spec.rb @@ -82,7 +82,7 @@ 'canceled_at' => nil, 'status' => nil, 'valid_to' => nil, - 'scheduled_plan' => nil, + 'scheduled_plan_name' => nil, 'plan' => { '@type' => 'v2_plan_config', '@representation' => 'standard', From 3877af18c615cffa7914f89c3fdb97bdcbdfb85d Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Mon, 30 Aug 2021 12:02:49 +0300 Subject: [PATCH 11/20] Fix spec --- spec/v3/models/v2_subscription_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/v3/models/v2_subscription_spec.rb b/spec/v3/models/v2_subscription_spec.rb index 8608cf8be3..7197bc5d10 100644 --- a/spec/v3/models/v2_subscription_spec.rb +++ b/spec/v3/models/v2_subscription_spec.rb @@ -8,6 +8,7 @@ 'status' => nil, 'valid_to' => nil, 'canceled_at' => nil, + 'scheduled_plan' => nil, 'billing_info' => { 'address' => 'Washington str.', 'address2' => '', @@ -32,6 +33,7 @@ 'starting_users' => 10000, 'private_credits' => 500000, 'public_credits' => 40000, + 'annual' => false, 'available_standalone_addons' => [ { 'id' => 'credits_25k', @@ -86,6 +88,7 @@ 'type' => 'credit_public', 'created_at' => Date.today.to_s, 'updated_at' => Date.today.to_s, + 'recurring' => false, 'current_usage_id' => 7, 'current_usage' => { 'id' => 7, From 01130c6a1cfd2ebd69b22cdf75ebe31288a73eb4 Mon Sep 17 00:00:00 2001 From: Stanislav Kolotinskiy Date: Mon, 6 Sep 2021 17:56:35 +0300 Subject: [PATCH 12/20] Implement credits calculator API --- lib/travis/api/v3/billing_client.rb | 7 ++ lib/travis/api/v3/models/credits_result.rb | 11 ++++ .../api/v3/queries/credits_calculator.rb | 10 +++ lib/travis/api/v3/renderer/credits_result.rb | 5 ++ lib/travis/api/v3/renderer/credits_results.rb | 6 ++ lib/travis/api/v3/routes.rb | 5 ++ lib/travis/api/v3/services.rb | 1 + .../services/credits_calculator/calculator.rb | 12 ++++ spec/support/billing_spec_helper.rb | 21 ++++++ spec/v3/billing_client_spec.rb | 24 +++++++ spec/v3/models/credits_result_spec.rb | 23 +++++++ .../credits_calculator/calculator_spec.rb | 66 +++++++++++++++++++ 12 files changed, 191 insertions(+) create mode 100644 lib/travis/api/v3/models/credits_result.rb create mode 100644 lib/travis/api/v3/queries/credits_calculator.rb create mode 100644 lib/travis/api/v3/renderer/credits_result.rb create mode 100644 lib/travis/api/v3/renderer/credits_results.rb create mode 100644 lib/travis/api/v3/services/credits_calculator/calculator.rb create mode 100644 spec/v3/models/credits_result_spec.rb create mode 100644 spec/v3/services/credits_calculator/calculator_spec.rb diff --git a/lib/travis/api/v3/billing_client.rb b/lib/travis/api/v3/billing_client.rb index 1678c8ef6e..2a171d5601 100644 --- a/lib/travis/api/v3/billing_client.rb +++ b/lib/travis/api/v3/billing_client.rb @@ -42,6 +42,13 @@ def executions(owner_type, owner_id, page, per_page, from, to) executions end + def calculate_credits(users, executions) + response = connection.post("/usage/credits_calculator", users: users, executions: executions) + response.body.map do |calculator_data| + Travis::API::V3::Models::CreditsResult.new(calculator_data) + end + end + def all data = connection.get('/subscriptions').body subscriptions = data.fetch('subscriptions').map do |subscription_data| diff --git a/lib/travis/api/v3/models/credits_result.rb b/lib/travis/api/v3/models/credits_result.rb new file mode 100644 index 0000000000..b26cc31656 --- /dev/null +++ b/lib/travis/api/v3/models/credits_result.rb @@ -0,0 +1,11 @@ +module Travis::API::V3 + class Models::CreditsResult + ATTRS = %w[users minutes os instance_size credits price] + + attr_accessor *ATTRS + + def initialize(attrs) + ATTRS.each { |key| send("#{key}=", attrs[key]) } + end + end +end diff --git a/lib/travis/api/v3/queries/credits_calculator.rb b/lib/travis/api/v3/queries/credits_calculator.rb new file mode 100644 index 0000000000..372d739ea9 --- /dev/null +++ b/lib/travis/api/v3/queries/credits_calculator.rb @@ -0,0 +1,10 @@ +module Travis::API::V3 + class Queries::CreditsCalculator < Query + params :users, :executions + + def calculate(user_id) + client = BillingClient.new(user_id) + client.calculate_credits(params['users'], params['executions']) + end + end +end diff --git a/lib/travis/api/v3/renderer/credits_result.rb b/lib/travis/api/v3/renderer/credits_result.rb new file mode 100644 index 0000000000..0ba570a8c7 --- /dev/null +++ b/lib/travis/api/v3/renderer/credits_result.rb @@ -0,0 +1,5 @@ +module Travis::API::V3 + class Renderer::CreditsResult < ModelRenderer + representation(:standard, :users, :minutes, :os, :instance_size, :credits, :price) + end +end diff --git a/lib/travis/api/v3/renderer/credits_results.rb b/lib/travis/api/v3/renderer/credits_results.rb new file mode 100644 index 0000000000..303f581513 --- /dev/null +++ b/lib/travis/api/v3/renderer/credits_results.rb @@ -0,0 +1,6 @@ +module Travis::API::V3 + class Renderer::CreditsResults < CollectionRenderer + type :credits_results + collection_key :credits_results + end +end diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index eecd02e2e3..dbc202a09f 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -155,6 +155,11 @@ module Routes end end + resource :credits_calculator do + route '/credits_calculator' + post :calculator + end + resource :repositories do route '/repos' get :for_current_user diff --git a/lib/travis/api/v3/services.rb b/lib/travis/api/v3/services.rb index 59d5e67df9..dc47f38fde 100644 --- a/lib/travis/api/v3/services.rb +++ b/lib/travis/api/v3/services.rb @@ -20,6 +20,7 @@ module Services BuildPermissions = Module.new { extend Services } Caches = Module.new { extend Services } Coupons = Module.new { extend Services } + CreditsCalculator = Module.new { extend Services } Cron = Module.new { extend Services } Crons = Module.new { extend Services } EmailSubscription = Module.new { extend Services } diff --git a/lib/travis/api/v3/services/credits_calculator/calculator.rb b/lib/travis/api/v3/services/credits_calculator/calculator.rb new file mode 100644 index 0000000000..a0dee86f39 --- /dev/null +++ b/lib/travis/api/v3/services/credits_calculator/calculator.rb @@ -0,0 +1,12 @@ +module Travis::API::V3 + class Services::CreditsCalculator::Calculator < Service + result_type :credits_results + params :users, :executions + + def run! + raise LoginRequired unless access_control.logged_in? + + result query(:credits_calculator).calculate(access_control.user.id) + end + end +end diff --git a/spec/support/billing_spec_helper.rb b/spec/support/billing_spec_helper.rb index 74395d77db..b4d377d4c9 100644 --- a/spec/support/billing_spec_helper.rb +++ b/spec/support/billing_spec_helper.rb @@ -242,6 +242,27 @@ def billing_v2_plan_response_body(attributes = {}) }.deep_merge(attributes) end + def billing_v2_credits_calculator_body + [ + { + 'users' => 3, + 'minutes' => nil, + 'os' => nil, + 'instance_size' => nil, + 'credits' => 25_000, + 'price' => 1_500 + }, + { + 'users' => nil, + 'minutes' => 1000, + 'os' => 'linux', + 'instance_size' => '2x-large', + 'credits' => 250_000, + 'price' => 15_000 + } + ] + end + def billing_coupon_response_body(attributes = {}) { "id" => "10_BUCKS_OFF", diff --git a/spec/v3/billing_client_spec.rb b/spec/v3/billing_client_spec.rb index 304e6e8a8b..cfbd22db2a 100644 --- a/spec/v3/billing_client_spec.rb +++ b/spec/v3/billing_client_spec.rb @@ -446,4 +446,28 @@ expect(stubbed_request).to have_been_made end end + + describe '#calculate_credits' do + let(:users) { 3 } + let(:executions) do + [ + { + minutes: '1000', + os: 'linux', + instance_size: '2x-large' + } + ] + end + + subject { billing.calculate_credits(users, executions) } + + it 'returns the results of the calculation' do + stub_request(:post, "#{billing_url}usage/credits_calculator").with(basic_auth: ['_', auth_key], headers: { 'X-Travis-User-Id' => user_id }) + .to_return(body: JSON.dump(billing_v2_credits_calculator_body)) + + expect(subject.first).to be_a(Travis::API::V3::Models::CreditsResult) + expect(subject.first.users).to eq(3) + expect(subject.last.os).to eq('linux') + end + end end diff --git a/spec/v3/models/credits_result_spec.rb b/spec/v3/models/credits_result_spec.rb new file mode 100644 index 0000000000..a4299a85cc --- /dev/null +++ b/spec/v3/models/credits_result_spec.rb @@ -0,0 +1,23 @@ +describe Travis::API::V3::Models::CreditsResult do + let(:user) { FactoryBot.create(:user) } + let(:attributes) do + { + 'users' => 5, + 'minutes' => 1200, + 'os' => 'linux', + 'instance_size' => '2x-large', + 'credits' => 25_000, + 'price' => 1_500 + } + end + + subject { Travis::API::V3::Models::CreditsResult.new(attributes) } + + context 'basic fields' do + it 'returns basic fields' do + attributes.each do |key, value| + expect(subject.send(key)).to eq(value) + end + end + end +end diff --git a/spec/v3/services/credits_calculator/calculator_spec.rb b/spec/v3/services/credits_calculator/calculator_spec.rb new file mode 100644 index 0000000000..983d0794f5 --- /dev/null +++ b/spec/v3/services/credits_calculator/calculator_spec.rb @@ -0,0 +1,66 @@ +describe Travis::API::V3::Services::CreditsCalculator::Calculator, set_app: true, billing_spec_helper: true do + let(:parsed_body) { JSON.load(last_response.body) } + let(:billing_url) { 'http://billingfake.travis-ci.com' } + let(:billing_auth_key) { 'secret' } + + before do + Travis.config.billing.url = billing_url + Travis.config.billing.auth_key = billing_auth_key + end + + context 'unauthenticated' do + it 'responds 403' do + post('/v3/credits_calculator', { users: 6, executions: [] }, {}) + + expect(last_response.status).to eq(403) + end + end + + context 'authenticated' do + let(:user) { FactoryBot.create(:user) } + let(:token) { Travis::Api::App::AccessToken.create(user: user, app_id: 1) } + let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} + + let(:v2_response_body) { JSON.dump(billing_v2_credits_calculator_body) } + + let(:expected_json) do + { + '@type' => 'credits_results', + '@representation' => 'standard', + 'credits_results' => [ + { + '@type' => 'credits_result', + '@representation' => 'standard', + 'users' => 3, + 'minutes' => nil, + 'os' => nil, + 'instance_size' => nil, + 'credits' => 25_000, + 'price' => 1_500 + }, + { + '@type' => 'credits_result', + '@representation' => 'standard', + 'users' => nil, + 'minutes' => 1000, + 'os' => 'linux', + 'instance_size' => '2x-large', + 'credits' => 250_000, + 'price' => 15_000 + } + ] + } + end + + before do + stub_billing_request(:post, '/usage/credits_calculator', auth_key: billing_auth_key, user_id: user.id) + .to_return(status: 200, body: v2_response_body) + end + + it 'responds with list of credits results' do + post('/v3/credits_calculator', { users: 6, executions: [] }, headers) + expect(last_response.status).to eq(200) + expect(parsed_body).to eql_json(expected_json) + end + end +end From 88578087ff7430b12e9c4a9de09d088c4b1feca6 Mon Sep 17 00:00:00 2001 From: Stanislav Kolotinskiy Date: Tue, 21 Sep 2021 18:48:48 +0300 Subject: [PATCH 13/20] Get default config for credits calculator --- lib/travis/api/v3/billing_client.rb | 6 +++ .../v3/models/credits_calculator_config.rb | 11 +++++ .../api/v3/queries/credits_calculator.rb | 5 ++ .../v3/renderer/credits_calculator_config.rb | 5 ++ lib/travis/api/v3/routes.rb | 1 + .../credits_calculator/default_config.rb | 11 +++++ spec/support/billing_spec_helper.rb | 9 ++++ spec/v3/billing_client_spec.rb | 13 +++++ .../models/credits_calculator_config_spec.rb | 21 ++++++++ .../credits_calculator/default_config_spec.rb | 48 +++++++++++++++++++ 10 files changed, 130 insertions(+) create mode 100644 lib/travis/api/v3/models/credits_calculator_config.rb create mode 100644 lib/travis/api/v3/renderer/credits_calculator_config.rb create mode 100644 lib/travis/api/v3/services/credits_calculator/default_config.rb create mode 100644 spec/v3/models/credits_calculator_config_spec.rb create mode 100644 spec/v3/services/credits_calculator/default_config_spec.rb diff --git a/lib/travis/api/v3/billing_client.rb b/lib/travis/api/v3/billing_client.rb index 2a171d5601..64c72bcf48 100644 --- a/lib/travis/api/v3/billing_client.rb +++ b/lib/travis/api/v3/billing_client.rb @@ -49,6 +49,12 @@ def calculate_credits(users, executions) end end + def credits_calculator_default_config + response = connection.get('/usage/credits_calculator/default_config') + + Travis::API::V3::Models::CreditsCalculatorConfig.new(response.body) + end + def all data = connection.get('/subscriptions').body subscriptions = data.fetch('subscriptions').map do |subscription_data| diff --git a/lib/travis/api/v3/models/credits_calculator_config.rb b/lib/travis/api/v3/models/credits_calculator_config.rb new file mode 100644 index 0000000000..0beb3ec654 --- /dev/null +++ b/lib/travis/api/v3/models/credits_calculator_config.rb @@ -0,0 +1,11 @@ +module Travis::API::V3 + class Models::CreditsCalculatorConfig + ATTRS = %w[users minutes os instance_size] + + attr_accessor *ATTRS + + def initialize(attrs) + ATTRS.each { |key| send("#{key}=", attrs[key]) } + end + end +end diff --git a/lib/travis/api/v3/queries/credits_calculator.rb b/lib/travis/api/v3/queries/credits_calculator.rb index 372d739ea9..ffef955455 100644 --- a/lib/travis/api/v3/queries/credits_calculator.rb +++ b/lib/travis/api/v3/queries/credits_calculator.rb @@ -6,5 +6,10 @@ def calculate(user_id) client = BillingClient.new(user_id) client.calculate_credits(params['users'], params['executions']) end + + def default_config(user_id) + client = BillingClient.new(user_id) + client.credits_calculator_default_config + end end end diff --git a/lib/travis/api/v3/renderer/credits_calculator_config.rb b/lib/travis/api/v3/renderer/credits_calculator_config.rb new file mode 100644 index 0000000000..b68350d22f --- /dev/null +++ b/lib/travis/api/v3/renderer/credits_calculator_config.rb @@ -0,0 +1,5 @@ +module Travis::API::V3 + class Renderer::CreditsCalculatorConfig < ModelRenderer + representation(:standard, :users, :minutes, :os, :instance_size) + end +end diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb index dbc202a09f..5ecd8407fa 100644 --- a/lib/travis/api/v3/routes.rb +++ b/lib/travis/api/v3/routes.rb @@ -158,6 +158,7 @@ module Routes resource :credits_calculator do route '/credits_calculator' post :calculator + get :default_config end resource :repositories do diff --git a/lib/travis/api/v3/services/credits_calculator/default_config.rb b/lib/travis/api/v3/services/credits_calculator/default_config.rb new file mode 100644 index 0000000000..2455a71862 --- /dev/null +++ b/lib/travis/api/v3/services/credits_calculator/default_config.rb @@ -0,0 +1,11 @@ +module Travis::API::V3 + class Services::CreditsCalculator::DefaultConfig < Service + result_type :credits_calculator_config + + def run! + raise LoginRequired unless access_control.logged_in? + + result query(:credits_calculator).default_config(access_control.user.id) + end + end +end diff --git a/spec/support/billing_spec_helper.rb b/spec/support/billing_spec_helper.rb index b4d377d4c9..20dd36b09b 100644 --- a/spec/support/billing_spec_helper.rb +++ b/spec/support/billing_spec_helper.rb @@ -263,6 +263,15 @@ def billing_v2_credits_calculator_body ] end + def billing_v2_credits_calculator_config_body + { + 'users' => 10, + 'minutes' => 1000, + 'os' => 'linux', + 'instance_size' => '2x-large' + } + end + def billing_coupon_response_body(attributes = {}) { "id" => "10_BUCKS_OFF", diff --git a/spec/v3/billing_client_spec.rb b/spec/v3/billing_client_spec.rb index cfbd22db2a..c326d70d09 100644 --- a/spec/v3/billing_client_spec.rb +++ b/spec/v3/billing_client_spec.rb @@ -470,4 +470,17 @@ expect(subject.last.os).to eq('linux') end end + + describe '#calculate_credits' do + subject { billing.credits_calculator_default_config } + + it 'returns the results of the calculation' do + stub_request(:get, "#{billing_url}usage/credits_calculator/default_config").with(basic_auth: ['_', auth_key], headers: { 'X-Travis-User-Id' => user_id }) + .to_return(body: JSON.dump(billing_v2_credits_calculator_config_body)) + + expect(subject).to be_a(Travis::API::V3::Models::CreditsCalculatorConfig) + expect(subject.users).to eq(10) + expect(subject.os).to eq('linux') + end + end end diff --git a/spec/v3/models/credits_calculator_config_spec.rb b/spec/v3/models/credits_calculator_config_spec.rb new file mode 100644 index 0000000000..f8e50df4b5 --- /dev/null +++ b/spec/v3/models/credits_calculator_config_spec.rb @@ -0,0 +1,21 @@ +describe Travis::API::V3::Models::CreditsResult do + let(:user) { FactoryBot.create(:user) } + let(:attributes) do + { + 'users' => 5, + 'minutes' => 1200, + 'os' => 'linux', + 'instance_size' => '2x-large' + } + end + + subject { Travis::API::V3::Models::CreditsCalculatorConfig.new(attributes) } + + context 'basic fields' do + it 'returns basic fields' do + attributes.each do |key, value| + expect(subject.send(key)).to eq(value) + end + end + end +end diff --git a/spec/v3/services/credits_calculator/default_config_spec.rb b/spec/v3/services/credits_calculator/default_config_spec.rb new file mode 100644 index 0000000000..dc15efd176 --- /dev/null +++ b/spec/v3/services/credits_calculator/default_config_spec.rb @@ -0,0 +1,48 @@ +describe Travis::API::V3::Services::CreditsCalculator::DefaultConfig, set_app: true, billing_spec_helper: true do + let(:parsed_body) { JSON.load(last_response.body) } + let(:billing_url) { 'http://billingfake.travis-ci.com' } + let(:billing_auth_key) { 'secret' } + + before do + Travis.config.billing.url = billing_url + Travis.config.billing.auth_key = billing_auth_key + end + + context 'unauthenticated' do + it 'responds 403' do + get('/v3/credits_calculator', { users: 6, executions: [] }, {}) + + expect(last_response.status).to eq(403) + end + end + + context 'authenticated' do + let(:user) { FactoryBot.create(:user) } + let(:token) { Travis::Api::App::AccessToken.create(user: user, app_id: 1) } + let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }} + + let(:v2_response_body) { JSON.dump(billing_v2_credits_calculator_config_body) } + + let(:expected_json) do + { + '@type' => 'credits_calculator_config', + '@representation' => 'standard', + 'users' => 10, + 'minutes' => 1000, + 'os' => 'linux', + 'instance_size' => '2x-large' + } + end + + before do + stub_billing_request(:get, '/usage/credits_calculator/default_config', auth_key: billing_auth_key, user_id: user.id) + .to_return(status: 200, body: v2_response_body) + end + + it 'responds with list of credits results' do + get('/v3/credits_calculator', {}, headers) + expect(last_response.status).to eq(200) + expect(parsed_body).to eql_json(expected_json) + end + end +end From 7d2adcc131c1aae861bfe825f619988c07385dc6 Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Wed, 22 Sep 2021 14:43:13 +0300 Subject: [PATCH 14/20] Fix spec --- spec/support/billing_spec_helper.rb | 19 +++++++++++++++++++ spec/v3/models/v2_subscription_spec.rb | 19 +++++++++++++++++++ .../services/v2_subscriptions/create_spec.rb | 19 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/spec/support/billing_spec_helper.rb b/spec/support/billing_spec_helper.rb index 20dd36b09b..8fb4cc17fe 100644 --- a/spec/support/billing_spec_helper.rb +++ b/spec/support/billing_spec_helper.rb @@ -63,6 +63,25 @@ def billing_v2_subscription_response_body(attributes={}) 'private_credits' => 500000, 'public_credits' => 40000, 'annual' => false, + 'refill_thresholds' => [10000, 50000, 100000], + 'refill_amounts' => [ + { + 'amount' => 25000, + 'price' => 1500 + }, + { + 'amount' => 100000, + 'price' => 6000 + }, + { + 'amount' => 200000, + 'price' => 6000 + }, + { + 'amount' => 400000, + 'price' => 12000 + } + ], 'available_standalone_addons' => [ { 'id' => 'credits_25k', diff --git a/spec/v3/models/v2_subscription_spec.rb b/spec/v3/models/v2_subscription_spec.rb index 7197bc5d10..9cbac0dcfa 100644 --- a/spec/v3/models/v2_subscription_spec.rb +++ b/spec/v3/models/v2_subscription_spec.rb @@ -34,6 +34,25 @@ 'private_credits' => 500000, 'public_credits' => 40000, 'annual' => false, + 'refill_thresholds' => [10000, 50000, 100000], + 'refill_amounts' => [ + { + 'amount' => 25000, + 'price' => 1500 + }, + { + 'amount' => 100000, + 'price' => 6000 + }, + { + 'amount' => 200000, + 'price' => 6000 + }, + { + 'amount' => 400000, + 'price' => 12000 + } + ], 'available_standalone_addons' => [ { 'id' => 'credits_25k', diff --git a/spec/v3/services/v2_subscriptions/create_spec.rb b/spec/v3/services/v2_subscriptions/create_spec.rb index 4733f933c7..5770f66f15 100644 --- a/spec/v3/services/v2_subscriptions/create_spec.rb +++ b/spec/v3/services/v2_subscriptions/create_spec.rb @@ -202,6 +202,25 @@ 'concurrency_limit' => 20, 'plan_type' => 'metered', 'annual' => false, + 'refill_thresholds' => [10000, 50000, 100000], + 'refill_amounts' => [ + { + 'amount' => 25000, + 'price' => 1500 + }, + { + 'amount' => 100000, + 'price' => 6000 + }, + { + 'amount' => 200000, + 'price' => 6000 + }, + { + 'amount' => 400000, + 'price' => 12000 + } + ], 'available_standalone_addons' => [ { 'id' => 'credits_25k', From 07944107c7757e43d3e1c13f32c44b511a354d5e Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Wed, 22 Sep 2021 14:52:05 +0300 Subject: [PATCH 15/20] Fix spec --- spec/support/billing_spec_helper.rb | 4 ++-- spec/v3/models/v2_subscription_spec.rb | 4 ++-- spec/v3/services/v2_subscriptions/all_spec.rb | 19 +++++++++++++++ .../services/v2_subscriptions/create_spec.rb | 23 +++++++++++++++++-- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/spec/support/billing_spec_helper.rb b/spec/support/billing_spec_helper.rb index 8fb4cc17fe..2ffe9f6227 100644 --- a/spec/support/billing_spec_helper.rb +++ b/spec/support/billing_spec_helper.rb @@ -63,8 +63,8 @@ def billing_v2_subscription_response_body(attributes={}) 'private_credits' => 500000, 'public_credits' => 40000, 'annual' => false, - 'refill_thresholds' => [10000, 50000, 100000], - 'refill_amounts' => [ + 'auto_refill_thresholds' => [10000, 50000, 100000], + 'auto_refill_amounts' => [ { 'amount' => 25000, 'price' => 1500 diff --git a/spec/v3/models/v2_subscription_spec.rb b/spec/v3/models/v2_subscription_spec.rb index 9cbac0dcfa..5933c7393d 100644 --- a/spec/v3/models/v2_subscription_spec.rb +++ b/spec/v3/models/v2_subscription_spec.rb @@ -34,8 +34,8 @@ 'private_credits' => 500000, 'public_credits' => 40000, 'annual' => false, - 'refill_thresholds' => [10000, 50000, 100000], - 'refill_amounts' => [ + 'auto_refill_thresholds' => [10000, 50000, 100000], + 'auto_refill_amounts' => [ { 'amount' => 25000, 'price' => 1500 diff --git a/spec/v3/services/v2_subscriptions/all_spec.rb b/spec/v3/services/v2_subscriptions/all_spec.rb index 6820dc9414..01cf10564b 100644 --- a/spec/v3/services/v2_subscriptions/all_spec.rb +++ b/spec/v3/services/v2_subscriptions/all_spec.rb @@ -96,6 +96,25 @@ 'private_credits' => 500_000, 'public_credits' => 40_000, 'annual' => false, + 'auto_refill_thresholds' => [10000, 50000, 100000], + 'auto_refill_amounts' => [ + { + 'amount' => 25000, + 'price' => 1500 + }, + { + 'amount' => 100000, + 'price' => 6000 + }, + { + 'amount' => 200000, + 'price' => 6000 + }, + { + 'amount' => 400000, + 'price' => 12000 + } + ], 'available_standalone_addons' => [ { 'id' => 'credits_25k', diff --git a/spec/v3/services/v2_subscriptions/create_spec.rb b/spec/v3/services/v2_subscriptions/create_spec.rb index 5770f66f15..34b5f2e4b7 100644 --- a/spec/v3/services/v2_subscriptions/create_spec.rb +++ b/spec/v3/services/v2_subscriptions/create_spec.rb @@ -84,6 +84,25 @@ 'private_credits' => 500_000, 'public_credits' => 40_000, 'annual' => false, + 'auto_refill_thresholds' => [10000, 50000, 100000], + 'auto_refill_amounts' => [ + { + 'amount' => 25000, + 'price' => 1500 + }, + { + 'amount' => 100000, + 'price' => 6000 + }, + { + 'amount' => 200000, + 'price' => 6000 + }, + { + 'amount' => 400000, + 'price' => 12000 + } + ], 'available_standalone_addons' => [ { 'id' => 'credits_25k', @@ -202,8 +221,8 @@ 'concurrency_limit' => 20, 'plan_type' => 'metered', 'annual' => false, - 'refill_thresholds' => [10000, 50000, 100000], - 'refill_amounts' => [ + 'auto_refill_thresholds' => [10000, 50000, 100000], + 'auto_refill_amounts' => [ { 'amount' => 25000, 'price' => 1500 From d7853b2ecc632f52f4659b63cc5772b2e5d4a7d7 Mon Sep 17 00:00:00 2001 From: Andrii Mysko Date: Wed, 22 Sep 2021 15:02:18 +0300 Subject: [PATCH 16/20] Fix spec --- spec/support/billing_spec_helper.rb | 19 +++++++++++++++++++ spec/v3/services/v2_subscriptions/all_spec.rb | 1 + .../services/v2_subscriptions/create_spec.rb | 1 + 3 files changed, 21 insertions(+) diff --git a/spec/support/billing_spec_helper.rb b/spec/support/billing_spec_helper.rb index 2ffe9f6227..b2cb0b16a5 100644 --- a/spec/support/billing_spec_helper.rb +++ b/spec/support/billing_spec_helper.rb @@ -257,6 +257,25 @@ def billing_v2_plan_response_body(attributes = {}) 'private_credits' => 10_000, 'public_credits' => 40_000, 'annual' => false, + 'auto_refill_thresholds' => [10000, 50000, 100000], + 'auto_refill_amounts' => [ + { + 'amount' => 25000, + 'price' => 1500 + }, + { + 'amount' => 100000, + 'price' => 6000 + }, + { + 'amount' => 200000, + 'price' => 6000 + }, + { + 'amount' => 400000, + 'price' => 12000 + } + ], 'available_standalone_addons' => [] }.deep_merge(attributes) end diff --git a/spec/v3/services/v2_subscriptions/all_spec.rb b/spec/v3/services/v2_subscriptions/all_spec.rb index 01cf10564b..6d5502826c 100644 --- a/spec/v3/services/v2_subscriptions/all_spec.rb +++ b/spec/v3/services/v2_subscriptions/all_spec.rb @@ -164,6 +164,7 @@ 'auto_refill' => { '@type' => 'auto_refill', '@representation' => 'minimal', + 'addon_id' => nil, 'enabled' => nil, 'threshold' => 25000, 'amount' => 10000 diff --git a/spec/v3/services/v2_subscriptions/create_spec.rb b/spec/v3/services/v2_subscriptions/create_spec.rb index 34b5f2e4b7..108a1cbdb9 100644 --- a/spec/v3/services/v2_subscriptions/create_spec.rb +++ b/spec/v3/services/v2_subscriptions/create_spec.rb @@ -289,6 +289,7 @@ 'auto_refill' => { '@type' => 'auto_refill', '@representation' => 'minimal', + 'addon_id' => nil, 'enabled' => nil, 'threshold' => 25000, 'amount' => 10000 From 64e4cd89a76195928aa2ba9072b5511257d7319b Mon Sep 17 00:00:00 2001 From: AndriiMysko Date: Mon, 27 Sep 2021 17:00:54 +0300 Subject: [PATCH 17/20] Fix coupons --- lib/travis/api/v3/services/v2_subscription/update_plan.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/travis/api/v3/services/v2_subscription/update_plan.rb b/lib/travis/api/v3/services/v2_subscription/update_plan.rb index 39fe276056..43a4c34ccf 100644 --- a/lib/travis/api/v3/services/v2_subscription/update_plan.rb +++ b/lib/travis/api/v3/services/v2_subscription/update_plan.rb @@ -1,6 +1,6 @@ module Travis::API::V3 class Services::V2Subscription::UpdatePlan < Service - params :plan + params :plan, :coupon def run! raise LoginRequired unless access_control.full_access_or_logged_in? From 5f992dadec271e76e57e30c3ad5b22b811d410f9 Mon Sep 17 00:00:00 2001 From: AndriiMysko Date: Tue, 16 Nov 2021 13:29:58 +0200 Subject: [PATCH 18/20] Fix merge typo --- lib/travis/api/v3/models/v2_plan_config.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/travis/api/v3/models/v2_plan_config.rb b/lib/travis/api/v3/models/v2_plan_config.rb index 0a11735323..e7933ef3c0 100644 --- a/lib/travis/api/v3/models/v2_plan_config.rb +++ b/lib/travis/api/v3/models/v2_plan_config.rb @@ -1,7 +1,7 @@ module Travis::API::V3 class Models::V2PlanConfig attr_reader :id, :name, :private_repos, :starting_price, :starting_users, :plan_type, - :private_credits, :public_credits, :addon_configs, :concurrency_limit, :available_standalone_addons, :auto_refill_enabled, :trial_plan + :private_credits, :public_credits, :addon_configs, :concurrency_limit, :available_standalone_addons, :auto_refill_enabled, :trial_plan, :annual, :auto_refill_thresholds, :auto_refill_amounts def initialize(attrs) From bb373afaad6cc5353e482849671e55014c5b3be9 Mon Sep 17 00:00:00 2001 From: Stanislav Kolotinskiy Date: Wed, 17 Nov 2021 18:17:25 +0200 Subject: [PATCH 19/20] Expose user_license_credits_consumed from executions model --- lib/travis/api/v3/models/executions.rb | 5 +++-- lib/travis/api/v3/renderer/execution.rb | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/travis/api/v3/models/executions.rb b/lib/travis/api/v3/models/executions.rb index a5e0f0dd85..255dbf65e6 100644 --- a/lib/travis/api/v3/models/executions.rb +++ b/lib/travis/api/v3/models/executions.rb @@ -1,8 +1,8 @@ module Travis::API::V3 class Models::Execution attr_reader :id, :os, :instance_size, :arch, :virtualization_type, :queue, :job_id, :repository_id, :owner_id, - :owner_type, :plan_id, :sender_id, :credits_consumed, :started_at, :finished_at, :created_at, - :updated_at + :owner_type, :plan_id, :sender_id, :credits_consumed, :user_license_credits_consumed, :started_at, + :finished_at, :created_at, :updated_at def initialize(attributes = {}) @id = attributes.fetch('id') @@ -18,6 +18,7 @@ def initialize(attributes = {}) @plan_id = attributes.fetch('plan_id') @sender_id = attributes.fetch('sender_id') @credits_consumed = attributes.fetch('credits_consumed') + @user_license_credits_consumed = attributes.fetch('user_license_credits_consumed') @started_at = attributes.fetch('started_at') @finished_at = attributes.fetch('finished_at') @created_at = attributes.fetch('created_at') diff --git a/lib/travis/api/v3/renderer/execution.rb b/lib/travis/api/v3/renderer/execution.rb index 093f825767..f54449ff61 100644 --- a/lib/travis/api/v3/renderer/execution.rb +++ b/lib/travis/api/v3/renderer/execution.rb @@ -1,8 +1,8 @@ module Travis::API::V3 class Renderer::Execution < ModelRenderer representation :minimal, :id, :os, :instance_size, :arch, :virtualization_type, :queue, :job_id, - :repository_id, :owner_id, :owner_type, :plan_id, :sender_id, :credits_consumed, :started_at, - :finished_at, :created_at, :updated_at + :repository_id, :owner_id, :owner_type, :plan_id, :sender_id, :credits_consumed, + :user_license_credits_consumed, :started_at, :finished_at, :created_at, :updated_at representation :standard, *representations[:minimal] end end From 15e837e400d3bbc9a09a67c17c6af8efe3096d40 Mon Sep 17 00:00:00 2001 From: Travis Architect Date: Mon, 13 Dec 2021 11:27:28 +0500 Subject: [PATCH 20/20] fixed specs --- spec/support/billing_spec_helper.rb | 1 + spec/v3/services/v2_subscription/executions_spec.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/spec/support/billing_spec_helper.rb b/spec/support/billing_spec_helper.rb index b2cb0b16a5..751ccb69dc 100644 --- a/spec/support/billing_spec_helper.rb +++ b/spec/support/billing_spec_helper.rb @@ -351,6 +351,7 @@ def billing_executions_response_body(attributes = {}) 'plan_id' => 2, 'sender_id' => 1, 'credits_consumed' => 5, + 'user_license_credits_consumed' => 4, 'started_at' => Time.now, 'finished_at' => Time.now + 10.minutes, 'created_at' => Time.now, diff --git a/spec/v3/services/v2_subscription/executions_spec.rb b/spec/v3/services/v2_subscription/executions_spec.rb index a3b446b15a..a20a1df70d 100644 --- a/spec/v3/services/v2_subscription/executions_spec.rb +++ b/spec/v3/services/v2_subscription/executions_spec.rb @@ -65,6 +65,7 @@ 'plan_id' => 2, 'sender_id' => 1, 'credits_consumed' => 5, + 'user_license_credits_consumed' => 4, 'started_at' => Time.now.to_s, 'finished_at' => (Time.now + 10.minutes).to_s, 'created_at' => Time.now.to_s,