dnsimple 8.6.0 → 8.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 644e524e7010bc680c34ba6abf09315fbe41e2a5ec63ee6c82e443df4f21326a
4
- data.tar.gz: aa84484bdf2a0b8b48ca45ad448dcea01c8c879acdf4b1c018f2cb8fb73ad7cf
3
+ metadata.gz: 71cf40738100b3388caeebb75622d78d73a3b1810711cfd9099b3f5fb97fbd43
4
+ data.tar.gz: 812bb20d76f731d08065dfa7703fd77a41e56cd9078f5a8f7c431f36df7d6a7d
5
5
  SHA512:
6
- metadata.gz: fa53931624fc7c23d8f91332c9d86379560fc3609fe0f351d6346b6e38fb5b9337bb04e0aa6120c639431b9931cbc100405bc7bca544e04ee805b1ef07e2d4cb
7
- data.tar.gz: 0032b9d9c4b3df0581e9037a5196bc8376c9f01dbb87ced552eb0372f6d30263a1121bdd86ba16e1a5a992974b64639cbdb81b9ba50e8442603bd0c6ab39f0b2
6
+ metadata.gz: fda1515e6b1d10f098f86c951d6f3d20af9bbbea762b062dd01ab4ebfa90f313c2fcf63718e93b016df05518101653edbb9d7cf0cd28e2d0870106ef9ee07e05
7
+ data.tar.gz: bfad72709061c258c83829366b7aa4fa5758fb3765eac93cc58748c737f644f8d4e35981d33d76104e6b4126f9b6ecb5cf28ea091b95c6e048f0fdbd8ac4738b
@@ -16,7 +16,7 @@ jobs:
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
18
  - name: Checkout Code
19
- uses: actions/checkout@v3
19
+ uses: actions/checkout@v4
20
20
  - name: Run markdownlint-cli
21
21
  uses: nosborn/github-action-markdown-cli@v3.3.0
22
22
  with:
@@ -37,7 +37,7 @@ jobs:
37
37
  - 'ruby-head'
38
38
  - 'truffleruby-head'
39
39
  steps:
40
- - uses: actions/checkout@v3
40
+ - uses: actions/checkout@v4
41
41
  - name: Set up Ruby
42
42
  uses: ruby/setup-ruby@v1
43
43
  with:
@@ -19,7 +19,7 @@ jobs:
19
19
  wait-interval: 10
20
20
  allowed-conclusions: success
21
21
 
22
- - uses: actions/checkout@v3
22
+ - uses: actions/checkout@v4
23
23
 
24
24
  - name: Release Gem
25
25
  uses: simplyqio/publish-rubygems-action@2.0.0
data/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ This project uses [Semantic Versioning 2.0.0](http://semver.org/).
4
4
 
5
5
  ## main
6
6
 
7
+ ## 8.7.0
8
+
9
+ FEATURES:
10
+
11
+ - NEW: Added `Dnsimple::Client::Billing#charges` to retrieve the list of billing charges for an account. (dnsimple/dnsimple-ruby#365)
12
+
7
13
  ## 8.6.0
8
14
 
9
15
  FEATURES:
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ source 'https://rubygems.org'
5
5
  gemspec
6
6
 
7
7
  gem 'coveralls', require: false
8
- gem 'rubocop', '1.56.2', require: false
9
- gem 'rubocop-performance', '1.19.0', require: false
8
+ gem 'rubocop', '1.57.1', require: false
9
+ gem 'rubocop-performance', '1.19.1', require: false
10
10
  gem 'rubocop-rake', '0.6.0', require: false
11
- gem 'rubocop-rspec', '2.23.2', require: false
11
+ gem 'rubocop-rspec', '2.24.1', require: false
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dnsimple
4
+ class Client
5
+ module Billing
6
+ # List the billing charges for the account.
7
+ #
8
+ # @see https://developer.dnsimple.com/v2/billing/#listCharges
9
+ #
10
+ # @example List charges in the first page
11
+ # client.charges.list(1010)
12
+ #
13
+ # @example List charges, provide a filter start date
14
+ # client.charges.list(1010, filter: { start_date: "2023-01-01" })
15
+ #
16
+ # @example List charges, provide a sorting policy
17
+ # client.charges.list(1010, sort: "invoiced:asc")
18
+ #
19
+ # @param [Integer] account_id the account ID
20
+ # @param [Hash] options the filtering and sorting options
21
+ # @option options [Integer] :page current page (pagination)
22
+ # @option options [Integer] :per_page number of entries to return (pagination)
23
+ # @option options [String] :sort sorting policy
24
+ # @return [Dnsimple::PaginatedResponse<Dnsimple::Struct::Charge>]
25
+ #
26
+ # @raise [Dnsimple::RequestError]
27
+ def charges(account_id, options = {})
28
+ response = client.get(Client.versioned("/%s/billing/charges" % [account_id]), Options::ListOptions.new(options))
29
+
30
+ Dnsimple::PaginatedResponse.new(response, response["data"].map { |r| Struct::Charge.new(r) })
31
+ end
32
+ alias list_charges charges
33
+ end
34
+ end
35
+ end
@@ -8,6 +8,11 @@ module Dnsimple
8
8
  @services[:accounts] ||= Client::AccountsService.new(self)
9
9
  end
10
10
 
11
+ # @return [Dnsimple::Client::BillingService] The billing-related API proxy.
12
+ def billing
13
+ @services[:billing] ||= Client::BillingService.new(self)
14
+ end
15
+
11
16
  # @return [Dnsimple::Client::CertificatesService] The certificate-related API proxy.
12
17
  def certificates
13
18
  @services[:certificates] ||= Client::CertificatesService.new(self)
@@ -115,6 +120,11 @@ module Dnsimple
115
120
  include Client::Accounts
116
121
  end
117
122
 
123
+ require_relative 'billing'
124
+
125
+ class BillingService < ClientService
126
+ include Client::Billing
127
+ end
118
128
 
119
129
  require_relative 'certificates'
120
130
 
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bigdecimal'
4
+
5
+ module Dnsimple
6
+ module Struct
7
+ class Charge < Base
8
+
9
+ class ChargeItem < Base
10
+ # @return [String] The description of the charge item.
11
+ attr_accessor :description
12
+
13
+ # @return [Float] The amount of the charge item.
14
+ attr_reader :amount
15
+
16
+ # @return [Integer] The ID of the product that was charged.
17
+ attr_accessor :product_id
18
+
19
+ # @return [String] The type of the product that was charged.
20
+ attr_accessor :product_type
21
+
22
+ # @return [String] A unique or representative reference.
23
+ attr_accessor :product_reference
24
+
25
+ # Converts amount to a Float and sets it.
26
+ #
27
+ # @param [String] amount
28
+ # @return [void]
29
+ def amount=(amount)
30
+ @amount = BigDecimal(amount)
31
+ end
32
+ end
33
+
34
+ # @return [String] The reference number of the invoice.
35
+ attr_accessor :reference
36
+
37
+ # @return [Float] The aggregate amount of all line items, that need to be paid.
38
+ attr_reader :total_amount
39
+
40
+ # @return [Float] The amount that was paid via wallet.
41
+ attr_reader :balance_amount
42
+
43
+ # @return [String] The state of the charge.
44
+ attr_accessor :state
45
+
46
+ # @return [DateTime] When the charge was invoiced.
47
+ attr_accessor :invoiced_at
48
+
49
+ # @return [Array<ChargeItems>] The charge items.
50
+ attr_reader :items
51
+
52
+ def initialize(*)
53
+ super
54
+ @items ||= []
55
+ end
56
+
57
+ # Converts items to an Array<Struct::Charge::ChargeItem> and sets it.
58
+ #
59
+ # @param [Array<Hash>] charge_items
60
+ # @return [void]
61
+ def items=(charge_items)
62
+ @items = charge_items.map do |charge_item|
63
+ Charge::ChargeItem.new(charge_item)
64
+ end
65
+ end
66
+
67
+ # Converts balance_amount to a Float and sets it.
68
+ #
69
+ # @param [String] balance_amount
70
+ # @return [void]
71
+ def balance_amount=(balance_amount)
72
+ @balance_amount = BigDecimal(balance_amount)
73
+ end
74
+
75
+ # Converts total_amount to a Float and sets it.
76
+ #
77
+ # @param [String] total_amount
78
+ # @return [void]
79
+ def total_amount=(total_amount)
80
+ @total_amount = BigDecimal(total_amount)
81
+ end
82
+ end
83
+
84
+ end
85
+ end
@@ -22,6 +22,7 @@ require_relative 'struct/certificate'
22
22
  require_relative 'struct/certificate_bundle'
23
23
  require_relative 'struct/certificate_purchase'
24
24
  require_relative 'struct/certificate_renewal'
25
+ require_relative 'struct/charge'
25
26
  require_relative 'struct/delegation_signer_record'
26
27
  require_relative 'struct/dnssec'
27
28
  require_relative 'struct/domain'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dnsimple
4
- VERSION = "8.6.0"
4
+ VERSION = "8.7.0"
5
5
  end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'bigdecimal/util'
6
+
7
+ describe Dnsimple::Client, ".billing" do
8
+
9
+ subject { described_class.new(base_url: "https://api.dnsimple.test", access_token: "a1b2c3").billing }
10
+
11
+ describe "#charges" do
12
+ let(:account_id) { 1010 }
13
+
14
+ before do
15
+ stub_request(:get, %r{/v2/#{account_id}/billing/charges})
16
+ .to_return(read_http_fixture("listCharges/success.http"))
17
+ end
18
+
19
+ it "builds the correct request" do
20
+ subject.charges(account_id)
21
+
22
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/billing/charges")
23
+ .with(headers: { 'Accept' => 'application/json' })
24
+ end
25
+
26
+ it "exposes the pagination information" do
27
+ response = subject.charges(account_id)
28
+
29
+ expect(response.respond_to?(:page)).to be(true)
30
+ expect(response.page).to eq(1)
31
+ expect(response.per_page).to be_a(Integer)
32
+ expect(response.total_entries).to be_a(Integer)
33
+ expect(response.total_pages).to be_a(Integer)
34
+ end
35
+
36
+ it "returns the charges" do
37
+ response = subject.charges(account_id)
38
+
39
+ expect(response).to be_a(Dnsimple::PaginatedResponse)
40
+ expect(response.data).to be_a(Array)
41
+ expect(response.data.size).to eq(3)
42
+
43
+ response.data.each do |result|
44
+ expect(result).to be_a(Dnsimple::Struct::Charge)
45
+ expect(result.balance_amount).to be_a(BigDecimal)
46
+ expect(result.reference).to be_a(String)
47
+ expect(result.items).to be_a(Array)
48
+ expect(result.items[0]).to be_a(Dnsimple::Struct::Charge::ChargeItem)
49
+ end
50
+
51
+ expect(response.data[0].total_amount).to be_a(BigDecimal)
52
+ expect(response.data[0].total_amount.to_s("F")).to eq("14.5")
53
+ expect(response.data[0].items[0].amount).to be_a(BigDecimal)
54
+ expect(response.data[0].items[0].amount.to_s("F")).to eq("14.5")
55
+ end
56
+
57
+ it "supports filters" do
58
+ subject.charges(account_id, filter: { start_date: "2023-01-01", end_date: "2023-08-31" })
59
+
60
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/billing/charges?start_date=2023-01-01&end_date=2023-08-31")
61
+ end
62
+
63
+ it "supports pagination" do
64
+ subject.charges(account_id, page: 2)
65
+
66
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/billing/charges?page=2")
67
+ end
68
+
69
+ it "supports sorting" do
70
+ subject.charges(account_id, sort: "invoiced:asc")
71
+
72
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/billing/charges?sort=invoiced:asc")
73
+ end
74
+
75
+ context "when using a bad filter" do
76
+ before do
77
+ stub_request(:get, %r{/v2/#{account_id}/billing/charges})
78
+ .to_return(read_http_fixture("listCharges/fail-400-bad-filter.http"))
79
+ end
80
+
81
+ it "raises error" do
82
+ expect do
83
+ subject.charges(account_id, filter: { start_date: "01-01-2023" })
84
+ end.to raise_error(Dnsimple::RequestError, "Invalid date format must be ISO8601 (YYYY-MM-DD)")
85
+ end
86
+ end
87
+
88
+ context "when account is not authorized" do
89
+ before do
90
+ stub_request(:get, %r{/v2/#{account_id}/billing/charges})
91
+ .to_return(read_http_fixture("listCharges/fail-403.http"))
92
+ end
93
+
94
+ it "raises error" do
95
+ expect do
96
+ subject.charges(account_id)
97
+ end.to raise_error(Dnsimple::RequestError, "Permission Denied. Required Scope: billing:*:read")
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,14 @@
1
+ HTTP/1.1 400 Bad Request
2
+ Date: Tue, 24 Oct 2023 08:13:01 GMT
3
+ Connection: close
4
+ X-RateLimit-Limit: 2400
5
+ X-RateLimit-Remaining: 2392
6
+ X-RateLimit-Reset: 1698136677
7
+ Content-Type: application/json; charset=utf-8
8
+ X-WORK-WITH-US: Love automation? So do we! https://dnsimple.com/jobs
9
+ Cache-Control: no-cache
10
+ X-Request-Id: bdfbf3a7-d9dc-4018-9732-61502be989a3
11
+ X-Runtime: 0.455303
12
+ Transfer-Encoding: chunked
13
+
14
+ {"message":"Invalid date format must be ISO8601 (YYYY-MM-DD)"}
@@ -0,0 +1,14 @@
1
+ HTTP/1.1 403 Forbidden
2
+ Date: Tue, 24 Oct 2023 09:49:29 GMT
3
+ Connection: close
4
+ X-RateLimit-Limit: 2400
5
+ X-RateLimit-Remaining: 2398
6
+ X-RateLimit-Reset: 1698143967
7
+ Content-Type: application/json; charset=utf-8
8
+ X-WORK-WITH-US: Love automation? So do we! https://dnsimple.com/jobs
9
+ Cache-Control: no-cache
10
+ X-Request-Id: 5554e2d3-2652-4ca7-8c5e-92b4c35f28d6
11
+ X-Runtime: 0.035309
12
+ Transfer-Encoding: chunked
13
+
14
+ {"message":"Permission Denied. Required Scope: billing:*:read"}
@@ -0,0 +1,14 @@
1
+ HTTP/1.1 200 OK
2
+ Date: Tue, 24 Oct 2023 09:52:55 GMT
3
+ Connection: close
4
+ X-RateLimit-Limit: 2400
5
+ X-RateLimit-Remaining: 2397
6
+ X-RateLimit-Reset: 1698143967
7
+ Content-Type: application/json; charset=utf-8
8
+ X-WORK-WITH-US: Love automation? So do we! https://dnsimple.com/jobs
9
+ Cache-Control: no-store, must-revalidate, private, max-age=0
10
+ X-Request-Id: a57a87c8-626a-4361-9fb8-b55ca9be8e5d
11
+ X-Runtime: 0.060526
12
+ Transfer-Encoding: chunked
13
+
14
+ {"data":[{"invoiced_at":"2023-08-17T05:53:36Z","total_amount":"14.50","balance_amount":"0.00","reference":"1-2","state":"collected","items":[{"description":"Register bubble-registered.com","amount":"14.50","product_id":1,"product_type":"domain-registration","product_reference":"bubble-registered.com"}]},{"invoiced_at":"2023-08-17T05:57:53Z","total_amount":"14.50","balance_amount":"0.00","reference":"2-2","state":"refunded","items":[{"description":"Register example.com","amount":"14.50","product_id":2,"product_type":"domain-registration","product_reference":"example.com"}]},{"invoiced_at":"2023-10-24T07:49:05Z","total_amount":"1099999.99","balance_amount":"0.00","reference":"4-2","state":"collected","items":[{"description":"Test Line Item 1","amount":"99999.99","product_id":null,"product_type":"manual","product_reference":null},{"description":"Test Line Item 2","amount":"1000000.00","product_id":null,"product_type":"manual","product_reference":null}]}],"pagination":{"current_page":1,"per_page":30,"total_entries":3,"total_pages":1}}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dnsimple
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.6.0
4
+ version: 8.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DNSimple
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-08 00:00:00.000000000 Z
11
+ date: 2023-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -110,6 +110,7 @@ files:
110
110
  - lib/dnsimple.rb
111
111
  - lib/dnsimple/client.rb
112
112
  - lib/dnsimple/client/accounts.rb
113
+ - lib/dnsimple/client/billing.rb
113
114
  - lib/dnsimple/client/certificates.rb
114
115
  - lib/dnsimple/client/clients.rb
115
116
  - lib/dnsimple/client/contacts.rb
@@ -149,6 +150,7 @@ files:
149
150
  - lib/dnsimple/struct/certificate_bundle.rb
150
151
  - lib/dnsimple/struct/certificate_purchase.rb
151
152
  - lib/dnsimple/struct/certificate_renewal.rb
153
+ - lib/dnsimple/struct/charge.rb
152
154
  - lib/dnsimple/struct/collaborator.rb
153
155
  - lib/dnsimple/struct/contact.rb
154
156
  - lib/dnsimple/struct/delegation_signer_record.rb
@@ -183,6 +185,7 @@ files:
183
185
  - lib/dnsimple/struct/zone_record.rb
184
186
  - lib/dnsimple/version.rb
185
187
  - spec/dnsimple/client/accounts_spec.rb
188
+ - spec/dnsimple/client/billing_spec.rb
186
189
  - spec/dnsimple/client/certificates_spec.rb
187
190
  - spec/dnsimple/client/client_service_spec.rb
188
191
  - spec/dnsimple/client/contacts_spec.rb
@@ -317,6 +320,9 @@ files:
317
320
  - spec/fixtures.http/listAccounts/success-account.http
318
321
  - spec/fixtures.http/listAccounts/success-user.http
319
322
  - spec/fixtures.http/listCertificates/success.http
323
+ - spec/fixtures.http/listCharges/fail-400-bad-filter.http
324
+ - spec/fixtures.http/listCharges/fail-403.http
325
+ - spec/fixtures.http/listCharges/success.http
320
326
  - spec/fixtures.http/listCollaborators/success.http
321
327
  - spec/fixtures.http/listContacts/success.http
322
328
  - spec/fixtures.http/listDelegationSignerRecords/success.http