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

Sign up to get free protection for your applications and to get access to all the features.
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