scalingo 3.0.0.beta.1 → 3.0.0.beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/CHANGELOG.md +13 -1
  4. data/README.md +41 -27
  5. data/lib/scalingo.rb +1 -1
  6. data/lib/scalingo/api/client.rb +34 -17
  7. data/lib/scalingo/api/endpoint.rb +1 -1
  8. data/lib/scalingo/api/response.rb +21 -32
  9. data/lib/scalingo/bearer_token.rb +11 -5
  10. data/lib/scalingo/billing.rb +11 -0
  11. data/lib/scalingo/billing/profile.rb +46 -0
  12. data/lib/scalingo/client.rb +52 -26
  13. data/lib/scalingo/configuration.rb +98 -0
  14. data/lib/scalingo/regional/addons.rb +2 -2
  15. data/lib/scalingo/regional/containers.rb +1 -1
  16. data/lib/scalingo/regional/events.rb +2 -2
  17. data/lib/scalingo/regional/logs.rb +1 -1
  18. data/lib/scalingo/regional/metrics.rb +1 -1
  19. data/lib/scalingo/regional/notifiers.rb +1 -1
  20. data/lib/scalingo/regional/operations.rb +9 -1
  21. data/lib/scalingo/version.rb +1 -1
  22. data/samples/billing/profile/_meta.json +23 -0
  23. data/samples/billing/profile/create-201.json +50 -0
  24. data/samples/billing/profile/create-400.json +27 -0
  25. data/samples/billing/profile/create-422.json +44 -0
  26. data/samples/billing/profile/show-200.json +41 -0
  27. data/samples/billing/profile/show-404.json +22 -0
  28. data/samples/billing/profile/update-200.json +47 -0
  29. data/samples/billing/profile/update-422.json +32 -0
  30. data/scalingo.gemspec +1 -3
  31. data/spec/scalingo/api/client_spec.rb +168 -0
  32. data/spec/scalingo/api/endpoint_spec.rb +30 -0
  33. data/spec/scalingo/api/response_spec.rb +285 -0
  34. data/spec/scalingo/auth_spec.rb +15 -0
  35. data/spec/scalingo/bearer_token_spec.rb +72 -0
  36. data/spec/scalingo/billing/profile_spec.rb +55 -0
  37. data/spec/scalingo/client_spec.rb +93 -0
  38. data/spec/scalingo/configuration_spec.rb +55 -0
  39. data/spec/scalingo/regional/operations_spec.rb +11 -3
  40. data/spec/scalingo/regional_spec.rb +14 -0
  41. metadata +33 -40
  42. data/Gemfile.lock +0 -110
  43. data/lib/scalingo/config.rb +0 -38
@@ -0,0 +1,15 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Scalingo::Auth do
4
+ subject { described_class.new(:client, :url) }
5
+
6
+ %w[keys scm_integrations tokens two_factor_auth user].each do |section|
7
+ it "handles requests for #{section}" do
8
+ expect(subject.respond_to?(section)).to be true
9
+ end
10
+ end
11
+
12
+ it "aliases tfa" do
13
+ expect(subject.tfa).to eq(subject.two_factor_auth)
14
+ end
15
+ end
@@ -0,0 +1,72 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Scalingo::BearerToken do
4
+ let(:value) { "my-token" }
5
+ let(:expires_at) { nil }
6
+ let(:raise_on_expired) { false }
7
+
8
+ subject { described_class.new(value, expires_at: expires_at, raise_on_expired: raise_on_expired) }
9
+
10
+ describe "initialize" do
11
+ it "stores the value" do
12
+ instance = described_class.new(:value)
13
+
14
+ expect(instance.value).to eq(:value)
15
+ expect(instance.expires_at).to eq nil
16
+ end
17
+
18
+ it "stores the expiration" do
19
+ expiration = Time.now + 1.hour
20
+ instance = described_class.new(:value, expires_at: expiration)
21
+
22
+ expect(instance.value).to eq(:value)
23
+ expect(instance.expires_at).to eq expiration
24
+ end
25
+ end
26
+
27
+ describe "expired?" do
28
+ context "without expiration" do
29
+ it { expect(subject).not_to be_expired }
30
+ end
31
+
32
+ context "with the expiration in the future" do
33
+ let(:expires_at) { Time.current + 1.hour }
34
+ it { expect(subject).not_to be_expired }
35
+ end
36
+
37
+ context "with the expiration in the past" do
38
+ let(:expires_at) { Time.current - 1.minute }
39
+ it { expect(subject).to be_expired }
40
+ end
41
+ end
42
+
43
+ describe "value" do
44
+ context "when raising on expired token" do
45
+ let(:raise_on_expired) { true }
46
+
47
+ it "raises when expired" do
48
+ expect(subject).to receive(:expired?).and_return(true)
49
+ expect { subject.value }.to raise_error(Scalingo::Error::ExpiredToken)
50
+ end
51
+
52
+ it "returns the value when not expired" do
53
+ expect(subject).to receive(:expired?).and_return(false)
54
+ expect(subject.value).to eq(value)
55
+ end
56
+ end
57
+
58
+ context "when not raising on expired token" do
59
+ let(:raise_on_expired) { false }
60
+
61
+ it "returns the value when expired" do
62
+ expect(subject).to receive(:expired?).and_return(true)
63
+ expect(subject.value).to eq(value)
64
+ end
65
+
66
+ it "returns the value when not expired" do
67
+ expect(subject).to receive(:expired?).and_return(false)
68
+ expect(subject.value).to eq(value)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Scalingo::Billing::Profile do
4
+ describe_method "show" do
5
+ context "existing" do
6
+ let(:stub_pattern) { "show-200" }
7
+
8
+ it_behaves_like "a singular object response"
9
+ end
10
+
11
+ context "not yet created" do
12
+ let(:stub_pattern) { "show-404" }
13
+
14
+ it_behaves_like "a not found response"
15
+ end
16
+ end
17
+
18
+ describe_method "create" do
19
+ context "success" do
20
+ let(:arguments) { meta[:create][:valid] }
21
+ let(:stub_pattern) { "create-201" }
22
+
23
+ it_behaves_like "a singular object response", 201
24
+ end
25
+
26
+ context "already existing" do
27
+ let(:stub_pattern) { "create-400" }
28
+
29
+ it_behaves_like "a client error"
30
+ end
31
+
32
+ context "unprocessable" do
33
+ let(:arguments) { meta[:create][:invalid] }
34
+ let(:stub_pattern) { "create-422" }
35
+
36
+ it_behaves_like "an unprocessable request"
37
+ end
38
+ end
39
+
40
+ describe_method "update" do
41
+ context "success" do
42
+ let(:arguments) { [meta[:id], meta[:update][:valid]] }
43
+ let(:stub_pattern) { "update-200" }
44
+
45
+ it_behaves_like "a singular object response"
46
+ end
47
+
48
+ context "unprocessable" do
49
+ let(:arguments) { [meta[:id], meta[:update][:invalid]] }
50
+ let(:stub_pattern) { "update-422" }
51
+
52
+ it_behaves_like "an unprocessable request"
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,93 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Scalingo::Client do
4
+ subject { described_class.new }
5
+
6
+ describe "token" do
7
+ it "wraps the token in a BearerToken" do
8
+ expect(subject.token).to eq nil
9
+
10
+ subject.token = "my-token"
11
+ expect(subject.token).to be_a(Scalingo::BearerToken)
12
+ expect(subject.token.value).to eq "my-token"
13
+
14
+ subject.token = Scalingo::BearerToken.new("other-token")
15
+ expect(subject.token).to be_a(Scalingo::BearerToken)
16
+ expect(subject.token.value).to eq "other-token"
17
+ end
18
+
19
+ it "can query the authentication status" do
20
+ expect(subject).not_to be_authenticated
21
+
22
+ subject.token = "my-token"
23
+ expect(subject).to be_authenticated
24
+
25
+ subject.token = Scalingo::BearerToken.new("other-token")
26
+ allow(subject.token).to receive(:expired?).and_return(false)
27
+ expect(subject).to be_authenticated
28
+
29
+ allow(subject.token).to receive(:expired?).and_return(true)
30
+ expect(subject).not_to be_authenticated
31
+ end
32
+ end
33
+
34
+ describe "authenticate_with" do
35
+ it "raises without arguments" do
36
+ expect { subject.authenticate_with }.to raise_error(ArgumentError)
37
+ end
38
+
39
+ it "raises with both more than one authentication type" do
40
+ expect {
41
+ subject.authenticate_with(access_token: :a, bearer_token: :b)
42
+ }.to raise_error(ArgumentError)
43
+ end
44
+
45
+ it "raises if expires_at is supplied for an access_token" do
46
+ expect {
47
+ subject.authenticate_with(access_token: :a, expires_at: :b)
48
+ }.to raise_error(ArgumentError)
49
+ end
50
+
51
+ context "with access token" do
52
+ it "is successful with valid token" do
53
+ fake_response = OpenStruct.new(
54
+ "successful?": true,
55
+ data: {token: "response token"},
56
+ )
57
+
58
+ expect(subject.auth.tokens).to receive(:exchange).and_return(fake_response)
59
+
60
+ expect(subject.authenticate_with(access_token: "access token")).to be true
61
+ expect(subject.token.value).to eq "response token"
62
+ expect(subject.token.expires_at).to be_within(1.second).of(Time.current + Scalingo.config.exchanged_token_validity)
63
+ end
64
+
65
+ it "fails with invalid token" do
66
+ fake_response = OpenStruct.new(
67
+ "successful?": false,
68
+ )
69
+
70
+ expect(subject.auth.tokens).to receive(:exchange).and_return(fake_response)
71
+
72
+ expect(subject.authenticate_with(access_token: "access token")).to be false
73
+ expect(subject.token).to be nil
74
+ end
75
+ end
76
+
77
+ context "with bearer token" do
78
+ it "only sets the bearer token according to the arguments" do
79
+ expect(subject.authenticate_with(bearer_token: "my token")).to be true
80
+ expect(subject.token.value).to eq "my token"
81
+ expect(subject.token.expires_at).to eq nil
82
+
83
+ expect(subject.authenticate_with(bearer_token: Scalingo::BearerToken.new("my token"))).to be true
84
+ expect(subject.token.value).to eq "my token"
85
+ expect(subject.token.expires_at).to eq nil
86
+
87
+ expect(subject.authenticate_with(bearer_token: "my token", expires_at: Time.now + 1.hour)).to be true
88
+ expect(subject.token.value).to eq "my token"
89
+ expect(subject.token.expires_at).not_to eq nil
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Scalingo::Configuration do
4
+ subject { described_class.default }
5
+
6
+ describe "default_region" do
7
+ it "must be an existing region" do
8
+ expect {
9
+ subject.default_region = "another-region"
10
+ }.to raise_error(ArgumentError)
11
+ end
12
+ end
13
+
14
+ describe "regions" do
15
+ it "can be assigned from a hash" do
16
+ subject.regions = {
17
+ local_name: "some-url"
18
+ }
19
+
20
+ expect(subject.regions.local_name).to eq "some-url"
21
+ end
22
+
23
+ it "can be assigned from a openstruct" do
24
+ subject.regions = OpenStruct.new(local_name: "some-url")
25
+
26
+ expect(subject.regions.local_name).to eq "some-url"
27
+ end
28
+
29
+ it "raises with an argument from the wrong type" do
30
+ expect {
31
+ subject.regions = "1"
32
+ }.to raise_error(ArgumentError)
33
+ end
34
+ end
35
+
36
+ describe "inheritance" do
37
+ it "can inherit configuration from a parent" do
38
+ object = described_class.new({}, subject)
39
+
40
+ described_class::ATTRIBUTES.each do |attr|
41
+ expect(object.public_send(attr)).to eq subject.public_send(attr)
42
+ end
43
+ end
44
+
45
+ it "can uses local configuration when supplied, the parent other wise" do
46
+ object = described_class.new({user_agent: "Agent"}, subject)
47
+
48
+ (described_class::ATTRIBUTES - [:user_agent]).each do |attr|
49
+ expect(object.public_send(attr)).to eq subject.public_send(attr)
50
+ end
51
+
52
+ expect(object.user_agent).to eq "Agent"
53
+ end
54
+ end
55
+ end
@@ -1,19 +1,27 @@
1
1
  require "spec_helper"
2
2
 
3
3
  RSpec.describe Scalingo::Regional::Operations do
4
- describe_method "find" do
4
+ describe_method "get" do
5
5
  context "success" do
6
- let(:arguments) { [meta[:app_id], meta[:id]] }
6
+ let(:arguments) { "apps/#{meta[:app_id]}/operations/#{meta[:id]}" }
7
7
  let(:stub_pattern) { "find-200" }
8
8
 
9
9
  it_behaves_like "a singular object response"
10
10
  end
11
11
 
12
12
  context "failure" do
13
- let(:arguments) { [meta[:app_id], meta[:not_found_id]] }
13
+ let(:arguments) { "apps/#{meta[:app_id]}/operations/#{meta[:not_found_id]}" }
14
14
  let(:stub_pattern) { "find-404" }
15
15
 
16
16
  it_behaves_like "a not found response"
17
17
  end
18
18
  end
19
+
20
+ describe_method "find" do
21
+ it "delegates to get" do
22
+ expect(subject).to receive(:get).with("apps/a/operations/b", :headers).once
23
+
24
+ subject.find(:a, :b, :headers)
25
+ end
26
+ end
19
27
  end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Scalingo::Regional do
4
+ subject { described_class.new(:client, :url) }
5
+
6
+ %w[
7
+ addons apps collaborators containers deployments domains environment events
8
+ logs metrics notifiers operations scm_repo_links
9
+ ].each do |section|
10
+ it "handles requests for #{section}" do
11
+ expect(subject.respond_to?(section)).to be true
12
+ end
13
+ end
14
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scalingo
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta.1
4
+ version: 3.0.0.beta.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leo Unbekandt
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-06-12 00:00:00.000000000 Z
12
+ date: 2020-06-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -31,40 +31,6 @@ dependencies:
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '7'
34
- - !ruby/object:Gem::Dependency
35
- name: activemodel
36
- requirement: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '5'
41
- - - "<"
42
- - !ruby/object:Gem::Version
43
- version: '7'
44
- type: :runtime
45
- prerelease: false
46
- version_requirements: !ruby/object:Gem::Requirement
47
- requirements:
48
- - - ">="
49
- - !ruby/object:Gem::Version
50
- version: '5'
51
- - - "<"
52
- - !ruby/object:Gem::Version
53
- version: '7'
54
- - !ruby/object:Gem::Dependency
55
- name: dry-configurable
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '0.11'
61
- type: :runtime
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '0.11'
68
34
  - !ruby/object:Gem::Dependency
69
35
  name: faraday
70
36
  requirement: !ruby/object:Gem::Requirement
@@ -133,14 +99,14 @@ dependencies:
133
99
  requirements:
134
100
  - - "~>"
135
101
  - !ruby/object:Gem::Version
136
- version: '10.0'
102
+ version: '13.0'
137
103
  type: :development
138
104
  prerelease: false
139
105
  version_requirements: !ruby/object:Gem::Requirement
140
106
  requirements:
141
107
  - - "~>"
142
108
  - !ruby/object:Gem::Version
143
- version: '10.0'
109
+ version: '13.0'
144
110
  - !ruby/object:Gem::Dependency
145
111
  name: rspec
146
112
  requirement: !ruby/object:Gem::Requirement
@@ -224,7 +190,6 @@ files:
224
190
  - ".travis.yml"
225
191
  - CHANGELOG.md
226
192
  - Gemfile
227
- - Gemfile.lock
228
193
  - LICENSE.txt
229
194
  - README.md
230
195
  - Rakefile
@@ -241,8 +206,10 @@ files:
241
206
  - lib/scalingo/auth/two_factor_auth.rb
242
207
  - lib/scalingo/auth/user.rb
243
208
  - lib/scalingo/bearer_token.rb
209
+ - lib/scalingo/billing.rb
210
+ - lib/scalingo/billing/profile.rb
244
211
  - lib/scalingo/client.rb
245
- - lib/scalingo/config.rb
212
+ - lib/scalingo/configuration.rb
246
213
  - lib/scalingo/error/expired_token.rb
247
214
  - lib/scalingo/error/unauthenticated.rb
248
215
  - lib/scalingo/errors.rb
@@ -300,6 +267,14 @@ files:
300
267
  - samples/auth/user/self.json
301
268
  - samples/auth/user/update-200.json
302
269
  - samples/auth/user/update-422.json
270
+ - samples/billing/profile/_meta.json
271
+ - samples/billing/profile/create-201.json
272
+ - samples/billing/profile/create-400.json
273
+ - samples/billing/profile/create-422.json
274
+ - samples/billing/profile/show-200.json
275
+ - samples/billing/profile/show-404.json
276
+ - samples/billing/profile/update-200.json
277
+ - samples/billing/profile/update-422.json
303
278
  - samples/regional/addons/_meta.json
304
279
  - samples/regional/addons/categories-guest.json
305
280
  - samples/regional/addons/categories-logged.json
@@ -421,11 +396,19 @@ files:
421
396
  - samples/regional/scm_repo_links/show-200.json
422
397
  - samples/regional/scm_repo_links/update-200.json
423
398
  - scalingo.gemspec
399
+ - spec/scalingo/api/client_spec.rb
400
+ - spec/scalingo/api/endpoint_spec.rb
401
+ - spec/scalingo/api/response_spec.rb
424
402
  - spec/scalingo/auth/keys_spec.rb
425
403
  - spec/scalingo/auth/scm_integrations_spec.rb
426
404
  - spec/scalingo/auth/tokens_spec.rb
427
405
  - spec/scalingo/auth/two_factor_auth_spec.rb
428
406
  - spec/scalingo/auth/user_spec.rb
407
+ - spec/scalingo/auth_spec.rb
408
+ - spec/scalingo/bearer_token_spec.rb
409
+ - spec/scalingo/billing/profile_spec.rb
410
+ - spec/scalingo/client_spec.rb
411
+ - spec/scalingo/configuration_spec.rb
429
412
  - spec/scalingo/regional/addons_spec.rb
430
413
  - spec/scalingo/regional/apps_spec.rb
431
414
  - spec/scalingo/regional/collaborators_spec.rb
@@ -439,6 +422,7 @@ files:
439
422
  - spec/scalingo/regional/notifiers_spec.rb
440
423
  - spec/scalingo/regional/operations_spec.rb
441
424
  - spec/scalingo/regional/scm_repo_links_spec.rb
425
+ - spec/scalingo/regional_spec.rb
442
426
  homepage: https://www.scalingo.com
443
427
  licenses:
444
428
  - MIT
@@ -468,11 +452,16 @@ signing_key:
468
452
  specification_version: 4
469
453
  summary: Ruby client for Scalingo APIs
470
454
  test_files:
455
+ - spec/scalingo/client_spec.rb
471
456
  - spec/scalingo/auth/scm_integrations_spec.rb
472
457
  - spec/scalingo/auth/tokens_spec.rb
473
458
  - spec/scalingo/auth/keys_spec.rb
474
459
  - spec/scalingo/auth/two_factor_auth_spec.rb
475
460
  - spec/scalingo/auth/user_spec.rb
461
+ - spec/scalingo/configuration_spec.rb
462
+ - spec/scalingo/api/client_spec.rb
463
+ - spec/scalingo/api/endpoint_spec.rb
464
+ - spec/scalingo/api/response_spec.rb
476
465
  - spec/scalingo/regional/collaborators_spec.rb
477
466
  - spec/scalingo/regional/operations_spec.rb
478
467
  - spec/scalingo/regional/notifiers_spec.rb
@@ -486,3 +475,7 @@ test_files:
486
475
  - spec/scalingo/regional/logs_spec.rb
487
476
  - spec/scalingo/regional/containers_spec.rb
488
477
  - spec/scalingo/regional/events_spec.rb
478
+ - spec/scalingo/bearer_token_spec.rb
479
+ - spec/scalingo/auth_spec.rb
480
+ - spec/scalingo/billing/profile_spec.rb
481
+ - spec/scalingo/regional_spec.rb