scalingo 3.3.0 → 3.5.0

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/dependabot.yml +17 -0
  3. data/.github/workflows/publish.yml +6 -3
  4. data/.github/workflows/ruby.yml +3 -3
  5. data/.rubocop.yml +9 -21
  6. data/CHANGELOG.md +10 -0
  7. data/README.md +1 -1
  8. data/lib/scalingo/api/client.rb +6 -15
  9. data/lib/scalingo/api/response.rb +3 -3
  10. data/lib/scalingo/auth/tokens.rb +2 -2
  11. data/lib/scalingo/auth.rb +1 -1
  12. data/lib/scalingo/billing.rb +1 -1
  13. data/lib/scalingo/client.rb +6 -6
  14. data/lib/scalingo/configuration.rb +3 -3
  15. data/lib/scalingo/core_client.rb +2 -3
  16. data/lib/scalingo/regional/addons.rb +1 -1
  17. data/lib/scalingo/regional.rb +1 -1
  18. data/lib/scalingo/regional_database/databases.rb +13 -0
  19. data/lib/scalingo/regional_database.rb +1 -1
  20. data/lib/scalingo/token_holder.rb +1 -1
  21. data/lib/scalingo/version.rb +1 -1
  22. data/samples/regional_database/backups/_meta.json +1 -1
  23. data/samples/regional_database/backups/archive-200.json +2 -2
  24. data/samples/regional_database/backups/archive-400.json +1 -1
  25. data/samples/regional_database/backups/create-201.json +1 -1
  26. data/samples/regional_database/backups/create-400.json +1 -1
  27. data/samples/regional_database/backups/for-200.json +1 -1
  28. data/samples/regional_database/backups/for-400.json +1 -1
  29. data/samples/regional_database/databases/_meta.json +1 -1
  30. data/samples/regional_database/databases/find-200.json +5 -3
  31. data/samples/regional_database/databases/find-400.json +1 -1
  32. data/samples/regional_database/databases/upgrade-202.json +39 -0
  33. data/samples/regional_database/databases/upgrade-400.json +24 -0
  34. data/scalingo.gemspec +4 -7
  35. metadata +13 -92
  36. data/spec/scalingo/api/client_spec.rb +0 -256
  37. data/spec/scalingo/api/endpoint_spec.rb +0 -45
  38. data/spec/scalingo/api/response_spec.rb +0 -301
  39. data/spec/scalingo/auth/keys_spec.rb +0 -58
  40. data/spec/scalingo/auth/scm_integrations_spec.rb +0 -58
  41. data/spec/scalingo/auth/tokens_spec.rb +0 -74
  42. data/spec/scalingo/auth/two_factor_auth_spec.rb +0 -69
  43. data/spec/scalingo/auth/user_spec.rb +0 -31
  44. data/spec/scalingo/auth_spec.rb +0 -15
  45. data/spec/scalingo/bearer_token_spec.rb +0 -72
  46. data/spec/scalingo/billing/profile_spec.rb +0 -55
  47. data/spec/scalingo/billing_spec.rb +0 -11
  48. data/spec/scalingo/client_spec.rb +0 -93
  49. data/spec/scalingo/configuration_spec.rb +0 -57
  50. data/spec/scalingo/core_client_spec.rb +0 -23
  51. data/spec/scalingo/regional/addons_spec.rb +0 -169
  52. data/spec/scalingo/regional/apps_spec.rb +0 -137
  53. data/spec/scalingo/regional/autoscalers_spec.rb +0 -84
  54. data/spec/scalingo/regional/collaborators_spec.rb +0 -69
  55. data/spec/scalingo/regional/containers_spec.rb +0 -67
  56. data/spec/scalingo/regional/deployments_spec.rb +0 -45
  57. data/spec/scalingo/regional/domains_spec.rb +0 -84
  58. data/spec/scalingo/regional/environment_spec.rb +0 -77
  59. data/spec/scalingo/regional/events_spec.rb +0 -65
  60. data/spec/scalingo/regional/logs_spec.rb +0 -39
  61. data/spec/scalingo/regional/metrics_spec.rb +0 -46
  62. data/spec/scalingo/regional/notifiers_spec.rb +0 -113
  63. data/spec/scalingo/regional/operations_spec.rb +0 -27
  64. data/spec/scalingo/regional/scm_repo_links_spec.rb +0 -48
  65. data/spec/scalingo/regional_database/backups_spec.rb +0 -58
  66. data/spec/scalingo/regional_database/databases_spec.rb +0 -23
  67. data/spec/scalingo/regional_database_spec.rb +0 -11
  68. data/spec/scalingo/regional_spec.rb +0 -14
  69. data/spec/scalingo/token_holder_spec.rb +0 -81
@@ -1,301 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Scalingo::API::Response do
4
- let(:client) { regional }
5
- let(:status) { 200 }
6
- let(:headers) { {} }
7
- let(:data) { "" }
8
- let(:full_body) { "" }
9
- let(:meta_object) { nil }
10
-
11
- subject {
12
- described_class.new(
13
- client: client,
14
- status: status,
15
- headers: headers,
16
- data: data,
17
- full_body: full_body,
18
- meta: meta_object,
19
- )
20
- }
21
-
22
- describe "self.unpack" do
23
- let(:body) { "" }
24
- let(:success) { true }
25
-
26
- let(:response) {
27
- OpenStruct.new(
28
- body: body,
29
- status: status,
30
- headers: headers,
31
- success?: success,
32
- )
33
- }
34
-
35
- it "passes the client supplied" do
36
- object = described_class.unpack(:some_client) { response }
37
-
38
- expect(object.client).to eq :some_client
39
- end
40
-
41
- it "passes the response status" do
42
- object = described_class.unpack(:client) { response }
43
-
44
- expect(object.status).to eq status
45
- end
46
-
47
- it "passes the response headers" do
48
- object = described_class.unpack(:client) { response }
49
-
50
- expect(object.headers).to eq headers
51
- end
52
-
53
- context "with an empty body" do
54
- let(:body) { "" }
55
-
56
- it "without key" do
57
- object = described_class.unpack(client) { response }
58
-
59
- expect(object.data).to eq ""
60
- expect(object.full_body).to eq ""
61
- expect(object.meta).to eq nil
62
- end
63
-
64
- it "ignores key if supplied" do
65
- object = described_class.unpack(client, key: :key) { response }
66
-
67
- expect(object.data).to eq ""
68
- expect(object.full_body).to eq ""
69
- expect(object.meta).to eq nil
70
- end
71
- end
72
-
73
- context "with a nil body" do
74
- let(:body) { nil }
75
-
76
- it "without key" do
77
- object = described_class.unpack(client) { response }
78
-
79
- expect(object.data).to eq nil
80
- expect(object.full_body).to eq nil
81
- expect(object.meta).to eq nil
82
- end
83
-
84
- it "ignores key if supplied" do
85
- object = described_class.unpack(client, key: :key) { response }
86
-
87
- expect(object.data).to eq nil
88
- expect(object.full_body).to eq nil
89
- expect(object.meta).to eq nil
90
- end
91
- end
92
-
93
- context "with a string body" do
94
- let(:body) { "this is a string body, probably due to an error" }
95
-
96
- it "without key" do
97
- object = described_class.unpack(client) { response }
98
-
99
- expect(object.data).to eq body
100
- expect(object.full_body).to eq body
101
- expect(object.meta).to eq nil
102
- end
103
-
104
- it "ignores key if supplied" do
105
- object = described_class.unpack(client, key: :key) { response }
106
-
107
- expect(object.data).to eq body
108
- expect(object.full_body).to eq body
109
- expect(object.meta).to eq nil
110
- end
111
- end
112
-
113
- context "with an json (array) body" do
114
- let(:body) {
115
- [{key: :value}]
116
- }
117
-
118
- it "without key" do
119
- object = described_class.unpack(client) { response }
120
-
121
- expect(object.data).to eq body
122
- expect(object.full_body).to eq body
123
- expect(object.meta).to eq nil
124
- end
125
-
126
- it "ignores key if supplied" do
127
- object = described_class.unpack(client, key: :root) { response }
128
-
129
- expect(object.data).to eq body
130
- expect(object.full_body).to eq body
131
- expect(object.meta).to eq nil
132
- end
133
- end
134
-
135
- context "with a json (hash) body" do
136
- let(:body) {
137
- {root: {key: :value}}
138
- }
139
-
140
- it "without key" do
141
- object = described_class.unpack(client) { response }
142
-
143
- expect(object.data).to eq body
144
- expect(object.full_body).to eq body
145
- expect(object.meta).to eq nil
146
- end
147
-
148
- it "with valid key" do
149
- object = described_class.unpack(client, key: :root) { response }
150
-
151
- expect(object.data).to eq({key: :value})
152
- expect(object.full_body).to eq body
153
- expect(object.meta).to eq nil
154
- end
155
-
156
- it "with invalid key" do
157
- object = described_class.unpack(client, key: :other) { response }
158
-
159
- expect(object.data).to eq nil
160
- expect(object.full_body).to eq body
161
- expect(object.meta).to eq nil
162
- end
163
-
164
- it "with valid keys" do
165
- object = described_class.unpack(client, keys: [:root, :key]) { response }
166
-
167
- expect(object.data).to eq(:value)
168
- expect(object.full_body).to eq body
169
- expect(object.meta).to eq nil
170
- end
171
-
172
- it "with invalid keys" do
173
- object = described_class.unpack(client, keys: [:root, :other]) { response }
174
-
175
- expect(object.data).to eq nil
176
- expect(object.full_body).to eq body
177
- expect(object.meta).to eq nil
178
- end
179
-
180
- context "with meta" do
181
- let(:body) {
182
- {root: {key: :value}, meta: {meta1: :value}}
183
- }
184
-
185
- it "extracts the meta object" do
186
- object = described_class.unpack(client) { response }
187
-
188
- expect(object.meta).to eq({meta1: :value})
189
- end
190
- end
191
- end
192
-
193
- context "with an error response" do
194
- let(:success) { false }
195
- let(:body) { {root: {key: :value}} }
196
-
197
- it "does not dig in the response hash, even with a valid key" do
198
- object = described_class.unpack(client, key: :root) { response }
199
-
200
- expect(object.data).to eq body
201
- expect(object.full_body).to eq body
202
- expect(object.meta).to eq nil
203
- end
204
- end
205
- end
206
-
207
- describe "successful?" do
208
- context "is true when 2XX" do
209
- let(:status) { 200 }
210
- it { expect(subject.successful?).to be true }
211
- end
212
-
213
- context "is false when 3XX" do
214
- let(:status) { 300 }
215
- it { expect(subject.successful?).to be false }
216
- end
217
-
218
- context "is false when 4XX" do
219
- let(:status) { 400 }
220
- it { expect(subject.successful?).to be false }
221
- end
222
-
223
- context "is false when 5XX" do
224
- let(:status) { 500 }
225
- it { expect(subject.successful?).to be false }
226
- end
227
- end
228
-
229
- describe "paginated?" do
230
- context "with pagination metadata" do
231
- let(:meta_object) {
232
- {pagination: {page: 1}}
233
- }
234
-
235
- it { expect(subject.paginated?).to be true }
236
- end
237
-
238
- context "without pagination metadata" do
239
- let(:meta_object) {
240
- {messages: []}
241
- }
242
-
243
- it { expect(subject.paginated?).to be false }
244
- end
245
- end
246
-
247
- describe "operation" do
248
- context "with an operation url" do
249
- before do
250
- load_meta!(api: :regional, folder: :operations)
251
- register_stubs!("find-200", api: :regional, folder: :operations)
252
- end
253
-
254
- let(:url) {
255
- path = "/apps/#{meta[:app_id]}/operations/#{meta[:id]}"
256
- File.join(Scalingo::ENDPOINTS[:regional], path)
257
- }
258
-
259
- let(:headers) {
260
- {location: url}
261
- }
262
-
263
- it { expect(subject.operation?).to be true }
264
- it { expect(subject.operation_url).to eq url }
265
-
266
- it "can request the operation" do
267
- response = subject.operation
268
-
269
- expect(response).to be_successful
270
- expect(response.data[:id]).to be_present
271
- expect(response.data[:status]).to be_present
272
- expect(response.data[:type]).to be_present
273
- end
274
-
275
- it "delegates the operation to the given client" do
276
- mock = double
277
-
278
- expect(subject.client).to receive(:operations).and_return(mock)
279
- expect(mock).to receive(:get).with(url).and_return(:response)
280
-
281
- expect(subject.operation).to eq :response
282
- end
283
-
284
- context "when the client doesn't know about operations" do
285
- let(:client) { auth }
286
-
287
- it "fails silently" do
288
- expect(subject.operation).to eq nil
289
- end
290
- end
291
- end
292
-
293
- context "without an operation url" do
294
- let(:meta_object) { {} }
295
-
296
- it { expect(subject.operation?).to be false }
297
- it { expect(subject.operation_url).to eq nil }
298
- it { expect(subject.operation).to eq nil }
299
- end
300
- end
301
- end
@@ -1,58 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Scalingo::Auth::Keys do
4
- describe_method "all" do
5
- let(:stub_pattern) { "all-200" }
6
-
7
- it_behaves_like "a collection response"
8
- it_behaves_like "a non-paginated collection"
9
- end
10
-
11
- describe_method "create" do
12
- context "success" do
13
- let(:arguments) { meta[:create][:valid] }
14
- let(:stub_pattern) { "create-201" }
15
-
16
- it_behaves_like "a singular object response", 201
17
- end
18
-
19
- context "unprocessable" do
20
- let(:arguments) { meta[:create][:invalid] }
21
- let(:stub_pattern) { "create-422" }
22
-
23
- it_behaves_like "an unprocessable request"
24
- end
25
- end
26
-
27
- describe_method "show" do
28
- context "success" do
29
- let(:arguments) { meta[:id] }
30
- let(:stub_pattern) { "show-200" }
31
-
32
- it_behaves_like "a singular object response"
33
- end
34
-
35
- context "not found" do
36
- let(:arguments) { meta[:not_found_id] }
37
- let(:stub_pattern) { "show-404" }
38
-
39
- it_behaves_like "a not found response"
40
- end
41
- end
42
-
43
- describe_method "destroy" do
44
- context "success" do
45
- let(:arguments) { meta[:id] }
46
- let(:stub_pattern) { "destroy-204" }
47
-
48
- it_behaves_like "an empty response"
49
- end
50
-
51
- context "not found" do
52
- let(:arguments) { meta[:not_found_id] }
53
- let(:stub_pattern) { "destroy-404" }
54
-
55
- it_behaves_like "a not found response"
56
- end
57
- end
58
- end
@@ -1,58 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Scalingo::Auth::ScmIntegrations do
4
- describe_method "all" do
5
- let(:stub_pattern) { "all-200" }
6
-
7
- it_behaves_like "a collection response"
8
- it_behaves_like "a non-paginated collection"
9
- end
10
-
11
- describe_method "create" do
12
- context "success" do
13
- let(:arguments) { meta[:create][:valid] }
14
- let(:stub_pattern) { "create-201" }
15
-
16
- it_behaves_like "a singular object response", 201
17
- end
18
-
19
- context "failure" do
20
- let(:arguments) { meta[:create][:invalid] }
21
- let(:stub_pattern) { "create-422" }
22
-
23
- it_behaves_like "an unprocessable request"
24
- end
25
- end
26
-
27
- describe_method "show" do
28
- context "success" do
29
- let(:arguments) { meta[:id] }
30
- let(:stub_pattern) { "show-200" }
31
-
32
- it_behaves_like "a singular object response"
33
- end
34
-
35
- context "not found" do
36
- let(:arguments) { meta[:not_found_id] }
37
- let(:stub_pattern) { "show-404" }
38
-
39
- it_behaves_like "a not found response"
40
- end
41
- end
42
-
43
- describe_method "destroy" do
44
- context "success" do
45
- let(:arguments) { meta[:id] }
46
- let(:stub_pattern) { "destroy-204" }
47
-
48
- it_behaves_like "an empty response"
49
- end
50
-
51
- context "not found" do
52
- let(:arguments) { meta[:not_found_id] }
53
- let(:stub_pattern) { "destroy-404" }
54
-
55
- it_behaves_like "a not found response"
56
- end
57
- end
58
- end
@@ -1,74 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Scalingo::Auth::Tokens do
4
- describe_method "exchange" do
5
- subject { auth_guest.tokens }
6
-
7
- context "with a valid token" do
8
- let(:arguments) { meta[:exchange][:valid] }
9
- let(:stub_pattern) { "exchange-200" }
10
-
11
- it "should be successful" do
12
- expect(response).to be_successful
13
- expect(response.data[:token]).to be_present
14
- end
15
- end
16
-
17
- context "with an invalid token" do
18
- let(:arguments) { meta[:exchange][:invalid] }
19
- let(:stub_pattern) { "exchange-401" }
20
-
21
- it "should be rejected with an valid token" do
22
- expect(response.status).to eq 401
23
- end
24
- end
25
- end
26
-
27
- describe_method "all" do
28
- let(:stub_pattern) { "all-200" }
29
-
30
- it_behaves_like "a collection response"
31
- it_behaves_like "a non-paginated collection"
32
- end
33
-
34
- describe_method "create" do
35
- context "success" do
36
- let(:arguments) { meta[:create][:valid] }
37
- let(:stub_pattern) { "create-201" }
38
-
39
- it_behaves_like "a singular object response", 201
40
- end
41
- end
42
-
43
- describe_method "renew" do
44
- context "success" do
45
- let(:arguments) { meta[:id] }
46
- let(:stub_pattern) { "renew-200" }
47
-
48
- it_behaves_like "a singular object response"
49
- end
50
-
51
- context "not found" do
52
- let(:arguments) { meta[:not_found_id] }
53
- let(:stub_pattern) { "renew-404" }
54
-
55
- it_behaves_like "a not found response"
56
- end
57
- end
58
-
59
- describe_method "destroy" do
60
- context "success" do
61
- let(:arguments) { meta[:id] }
62
- let(:stub_pattern) { "destroy-204" }
63
-
64
- it_behaves_like "an empty response"
65
- end
66
-
67
- context "not found" do
68
- let(:arguments) { meta[:not_found_id] }
69
- let(:stub_pattern) { "destroy-404" }
70
-
71
- it_behaves_like "a not found response"
72
- end
73
- end
74
- end
@@ -1,69 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Scalingo::Auth::TwoFactorAuth do
4
- describe_method "status" do
5
- let(:stub_pattern) { "status" }
6
-
7
- it_behaves_like "a singular object response"
8
- end
9
-
10
- describe_method "initiate" do
11
- context "success" do
12
- let(:arguments) { Scalingo::Auth::TwoFactorAuth::DEFAULT_PROVIDER }
13
- let(:stub_pattern) { "initiate-success" }
14
-
15
- it_behaves_like "a singular object response", 201
16
- end
17
-
18
- context "wrong provider" do
19
- let(:arguments) { meta[:initiate][:invalid] }
20
- let(:stub_pattern) { "initiate-wrong-provider" }
21
-
22
- it_behaves_like "a client error"
23
- end
24
-
25
- context "already enabled" do
26
- let(:stub_pattern) { "initiate-already-enabled" }
27
-
28
- it_behaves_like "a client error"
29
- end
30
- end
31
-
32
- describe_method "validate" do
33
- context "success" do
34
- let(:arguments) { meta[:validate][:valid] }
35
- let(:stub_pattern) { "validate-success" }
36
- let(:expected_keys) { %i[codes user] }
37
-
38
- it_behaves_like "a singular object response", 201
39
- end
40
-
41
- context "wrong provider" do
42
- let(:arguments) { meta[:validate][:invalid] }
43
- let(:stub_pattern) { "validate-wrong" }
44
-
45
- it_behaves_like "a client error"
46
- end
47
-
48
- context "already enabled" do
49
- let(:arguments) { meta[:validate][:invalid] }
50
- let(:stub_pattern) { "validate-not-initiated" }
51
-
52
- it_behaves_like "a client error"
53
- end
54
- end
55
-
56
- describe_method "disable" do
57
- context "success" do
58
- let(:stub_pattern) { "disable-success" }
59
-
60
- it_behaves_like "a singular object response"
61
- end
62
-
63
- context "not enabled" do
64
- let(:stub_pattern) { "disable-not-initiated" }
65
-
66
- it_behaves_like "a client error"
67
- end
68
- end
69
- end
@@ -1,31 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Scalingo::Auth::User do
4
- describe_method "self" do
5
- let(:stub_pattern) { "self" }
6
-
7
- it_behaves_like "a singular object response"
8
- end
9
-
10
- describe_method "update" do
11
- context "success" do
12
- let(:arguments) { meta[:update][:valid] }
13
- let(:stub_pattern) { "update-200" }
14
-
15
- it_behaves_like "a singular object response"
16
- end
17
-
18
- context "unprocessable" do
19
- let(:arguments) { meta[:update][:invalid] }
20
- let(:stub_pattern) { "update-422" }
21
-
22
- it_behaves_like "an unprocessable request"
23
- end
24
- end
25
-
26
- describe_method "stop_free_trial" do
27
- let(:stub_pattern) { "stop-free-trial" }
28
-
29
- it_behaves_like "a successful response"
30
- end
31
- end
@@ -1,15 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe Scalingo::Auth do
4
- subject { described_class.new("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
@@ -1,72 +0,0 @@
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