diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md index 6e3a55f721c5a993f81fbc75e67535fec4b313de..797d74b5935f81517e272709e0c4ef9aee59ffa4 100644 --- a/doc/api/graphql/reference/_index.md +++ b/doc/api/graphql/reference/_index.md @@ -31255,6 +31255,7 @@ Describes the usage of consumables under the subscription. | Name | Type | Description | | ---- | ---- | ----------- | +| `enabled` | [`Boolean!`](#boolean) | Indicates if the Customer Portal GitLab Credits API is enabled. | | `endDate` | [`ISO8601Date`](#iso8601date) | End date of the period covered by the usage data. | | `isOutdatedClient` | [`Boolean`](#boolean) | Indicates if the GitLab instance has an outdated API contract with the Customer Portal. | | `lastEventTransactionAt` | [`ISO8601DateTime`](#iso8601datetime) | Date and time when the last usage event resulted in a wallet transaction. | diff --git a/ee/app/graphql/types/gitlab_subscriptions/subscription_usage_type.rb b/ee/app/graphql/types/gitlab_subscriptions/subscription_usage_type.rb index 0ef8d0980772b18c6716dd148dffa70a75152433..0d506876432317cf3fb90cfb5f506010260794cb 100644 --- a/ee/app/graphql/types/gitlab_subscriptions/subscription_usage_type.rb +++ b/ee/app/graphql/types/gitlab_subscriptions/subscription_usage_type.rb @@ -8,6 +8,11 @@ class SubscriptionUsageType < BaseObject authorize :read_subscription_usage + field :enabled, GraphQL::Types::Boolean, + null: false, + method: :enabled?, + description: 'Indicates if the Customer Portal GitLab Credits API is enabled.' + field :is_outdated_client, GraphQL::Types::Boolean, null: true, method: :outdated_client?, diff --git a/ee/lib/gitlab/subscription_portal/subscription_usage_client.rb b/ee/lib/gitlab/subscription_portal/subscription_usage_client.rb index 068e1ab340c45ceeb3e44fb05916ab3e347f0074..94e13c3e11cc812d3586baa7aba646fac177dda7 100644 --- a/ee/lib/gitlab/subscription_portal/subscription_usage_client.rb +++ b/ee/lib/gitlab/subscription_portal/subscription_usage_client.rb @@ -18,6 +18,7 @@ class SubscriptionUsageClient < Client gitlabCreditsUsage(instanceId: $instanceId) { startDate endDate + enabled isOutdatedClient(gitlabVersion: $gitlabVersion) lastEventTransactionAt purchaseCreditsPath diff --git a/ee/lib/gitlab_subscriptions/subscription_usage.rb b/ee/lib/gitlab_subscriptions/subscription_usage.rb index 526930c46a5530b497273868acc8ff8c0ce9fd7f..1209a83986ecaabf684ce2042ab37c44ec898354 100644 --- a/ee/lib/gitlab_subscriptions/subscription_usage.rb +++ b/ee/lib/gitlab_subscriptions/subscription_usage.rb @@ -21,6 +21,10 @@ def initialize( attr_reader :namespace, :subscription_usage_client, :subscription_target + def enabled? + !!usage_metadata[:enabled] + end + def outdated_client? usage_metadata[:isOutdatedClient] end diff --git a/ee/spec/graphql/types/gitlab_subscriptions/subscription_usage_type_spec.rb b/ee/spec/graphql/types/gitlab_subscriptions/subscription_usage_type_spec.rb index 93fb1dddd8b776d7c183b8153616d994e9ea806d..475a0b4b340d30749f249bb6c4092f41649212af 100644 --- a/ee/spec/graphql/types/gitlab_subscriptions/subscription_usage_type_spec.rb +++ b/ee/spec/graphql/types/gitlab_subscriptions/subscription_usage_type_spec.rb @@ -8,6 +8,7 @@ it 'has expected fields' do expect(described_class).to have_graphql_fields([ + :enabled, :is_outdated_client, :last_event_transaction_at, :start_date, diff --git a/ee/spec/lib/gitlab/subscription_portal/subscription_usage_client_spec.rb b/ee/spec/lib/gitlab/subscription_portal/subscription_usage_client_spec.rb index 044c19dcbcd88ae4fd05a3eefa33c243db257a54..470044717534698d2decc5ffde3ee9edec672ba6 100644 --- a/ee/spec/lib/gitlab/subscription_portal/subscription_usage_client_spec.rb +++ b/ee/spec/lib/gitlab/subscription_portal/subscription_usage_client_spec.rb @@ -145,6 +145,7 @@ gitlabCreditsUsage: { startDate: "2025-10-01", endDate: "2025-10-31", + enabled: true, isOutdatedClient: false, lastEventTransactionAt: "2025-10-01T16:19:59Z", purchaseCreditsPath: '/mock/path' @@ -160,6 +161,7 @@ subscriptionUsage: { startDate: "2025-10-01", endDate: "2025-10-31", + enabled: true, isOutdatedClient: false, lastEventTransactionAt: "2025-10-01T16:19:59Z", purchaseCreditsPath: '/mock/path' diff --git a/ee/spec/lib/gitlab_subscriptions/subscription_usage_spec.rb b/ee/spec/lib/gitlab_subscriptions/subscription_usage_spec.rb index 34334acbdd599342ddd0334deb21d01b82979ade..64119bbaaf8f021fb40b8358fa4715b9fdfc554d 100644 --- a/ee/spec/lib/gitlab_subscriptions/subscription_usage_spec.rb +++ b/ee/spec/lib/gitlab_subscriptions/subscription_usage_spec.rb @@ -195,6 +195,37 @@ end end + describe '#enabled?' do + where(:cdot_enabled_value, :return_value) do + true | true + false | false + nil | false + end + + with_them do + before do + allow(subscription_usage_client).to receive(:get_metadata).and_return(client_response) + end + + context "when subscription portal returns #{params[:cdot_enabled_value]} for enabled" do + let(:subscription_usage) do + described_class.new( + subscription_target: :instance, + subscription_usage_client: subscription_usage_client + ) + end + + let(:client_response) do + { success: true, subscriptionUsage: { enabled: cdot_enabled_value } } + end + + it "returns #{params[:return_value]} for enabled?" do + expect(subscription_usage.enabled?).to be return_value + end + end + end + end + describe '#outdated_client?' do where(:outdated_client) { [true, false] } diff --git a/ee/spec/requests/api/graphql/gitlab_subscriptions/subscription_usage_spec.rb b/ee/spec/requests/api/graphql/gitlab_subscriptions/subscription_usage_spec.rb index 28aff5dcbe871f6dda82a108670f5ba476800785..71bf974048e93f4db6cba5e1a399c850ef496719 100644 --- a/ee/spec/requests/api/graphql/gitlab_subscriptions/subscription_usage_spec.rb +++ b/ee/spec/requests/api/graphql/gitlab_subscriptions/subscription_usage_spec.rb @@ -58,6 +58,7 @@ let(:user_arguments) { {} } let(:query_fields) do [ + :enabled, :is_outdated_client, :last_event_transaction_at, :start_date, @@ -127,6 +128,20 @@ ) end + let(:metadata) do + { + success: true, + subscriptionUsage: { + startDate: "2025-10-01", + endDate: "2025-10-31", + enabled: true, + isOutdatedClient: false, + lastEventTransactionAt: "2025-10-01T16:19:59Z", + purchaseCreditsPath: '/mock/path' + } + } + end + shared_examples 'empty response' do it 'returns nil for subscription usage' do post_graphql(query, current_user: current_user) @@ -144,17 +159,6 @@ before do stub_feature_flags(usage_billing_dev: true) - metadata = { - success: true, - subscriptionUsage: { - startDate: "2025-10-01", - endDate: "2025-10-31", - isOutdatedClient: false, - lastEventTransactionAt: "2025-10-01T16:19:59Z", - purchaseCreditsPath: '/mock/path' - } - } - events_for_user_id = { nodes: [ { @@ -265,6 +269,7 @@ end it 'returns subscription usage for instance' do + expect(graphql_data_at(:subscription_usage, :enabled)).to be true expect(graphql_data_at(:subscription_usage, :isOutdatedClient)).to be false expect(graphql_data_at(:subscription_usage, :lastEventTransactionAt)).to eq("2025-10-01T16:19:59Z") expect(graphql_data_at(:subscription_usage, :startDate)).to eq("2025-10-01") @@ -315,6 +320,22 @@ ) end + context 'when the CustomersDot subscription_usage API is not enabled' do + let(:query_fields) { [:enabled] } + let(:metadata) do + { + success: true, + subscriptionUsage: { + enabled: false + } + } + end + + it 'returns subscription usage for the group' do + expect(graphql_data_at(:subscription_usage, :enabled)).to be false + end + end + context 'when filtering users by username' do let(:user_arguments) { { username: maintainer.username } } @@ -384,6 +405,7 @@ end it 'returns subscription usage for the group' do + expect(graphql_data_at(:subscription_usage, :enabled)).to be true expect(graphql_data_at(:subscription_usage, :isOutdatedClient)).to be false expect(graphql_data_at(:subscription_usage, :lastEventTransactionAt)).to eq("2025-10-01T16:19:59Z") expect(graphql_data_at(:subscription_usage, :startDate)).to eq("2025-10-01") @@ -434,6 +456,22 @@ ) end + context 'when the CustomersDot subscription_usage API is not enabled' do + let(:query_fields) { [:enabled] } + let(:metadata) do + { + success: true, + subscriptionUsage: { + enabled: false + } + } + end + + it 'returns subscription usage for the group' do + expect(graphql_data_at(:subscription_usage, :enabled)).to be false + end + end + context 'when filtering users by username' do let(:user_arguments) { { username: maintainer.username } }