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 +4 -4
- data/.github/workflows/ci.yml +2 -2
- data/.github/workflows/release.yml +1 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile +3 -3
- data/lib/dnsimple/client/billing.rb +35 -0
- data/lib/dnsimple/client/clients.rb +10 -0
- data/lib/dnsimple/struct/charge.rb +85 -0
- data/lib/dnsimple/struct.rb +1 -0
- data/lib/dnsimple/version.rb +1 -1
- data/spec/dnsimple/client/billing_spec.rb +101 -0
- data/spec/fixtures.http/listCharges/fail-400-bad-filter.http +14 -0
- data/spec/fixtures.http/listCharges/fail-403.http +14 -0
- data/spec/fixtures.http/listCharges/success.http +14 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71cf40738100b3388caeebb75622d78d73a3b1810711cfd9099b3f5fb97fbd43
|
4
|
+
data.tar.gz: 812bb20d76f731d08065dfa7703fd77a41e56cd9078f5a8f7c431f36df7d6a7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fda1515e6b1d10f098f86c951d6f3d20af9bbbea762b062dd01ab4ebfa90f313c2fcf63718e93b016df05518101653edbb9d7cf0cd28e2d0870106ef9ee07e05
|
7
|
+
data.tar.gz: bfad72709061c258c83829366b7aa4fa5758fb3765eac93cc58748c737f644f8d4e35981d33d76104e6b4126f9b6ecb5cf28ea091b95c6e048f0fdbd8ac4738b
|
data/.github/workflows/ci.yml
CHANGED
@@ -16,7 +16,7 @@ jobs:
|
|
16
16
|
runs-on: ubuntu-latest
|
17
17
|
steps:
|
18
18
|
- name: Checkout Code
|
19
|
-
uses: actions/checkout@
|
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@
|
40
|
+
- uses: actions/checkout@v4
|
41
41
|
- name: Set up Ruby
|
42
42
|
uses: ruby/setup-ruby@v1
|
43
43
|
with:
|
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.
|
9
|
-
gem 'rubocop-performance', '1.19.
|
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.
|
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
|
data/lib/dnsimple/struct.rb
CHANGED
@@ -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'
|
data/lib/dnsimple/version.rb
CHANGED
@@ -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.
|
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-
|
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
|