aptible-cli 0.14.1 → 0.15.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.
- checksums.yaml +4 -4
- data/README.md +10 -1
- data/aptible-cli.gemspec +1 -0
- data/bin/aptible +9 -5
- data/lib/aptible/cli.rb +36 -0
- data/lib/aptible/cli/agent.rb +10 -6
- data/lib/aptible/cli/error.rb +6 -0
- data/lib/aptible/cli/formatter.rb +21 -0
- data/lib/aptible/cli/formatter/grouped_keyed_list.rb +54 -0
- data/lib/aptible/cli/formatter/keyed_list.rb +25 -0
- data/lib/aptible/cli/formatter/keyed_object.rb +16 -0
- data/lib/aptible/cli/formatter/list.rb +33 -0
- data/lib/aptible/cli/formatter/node.rb +8 -0
- data/lib/aptible/cli/formatter/object.rb +38 -0
- data/lib/aptible/cli/formatter/root.rb +46 -0
- data/lib/aptible/cli/formatter/value.rb +25 -0
- data/lib/aptible/cli/helpers/app.rb +1 -0
- data/lib/aptible/cli/helpers/database.rb +22 -6
- data/lib/aptible/cli/helpers/operation.rb +3 -2
- data/lib/aptible/cli/helpers/tunnel.rb +1 -3
- data/lib/aptible/cli/helpers/vhost.rb +9 -46
- data/lib/aptible/cli/renderer.rb +26 -0
- data/lib/aptible/cli/renderer/base.rb +8 -0
- data/lib/aptible/cli/renderer/json.rb +26 -0
- data/lib/aptible/cli/renderer/text.rb +99 -0
- data/lib/aptible/cli/resource_formatter.rb +136 -0
- data/lib/aptible/cli/subcommands/apps.rb +26 -14
- data/lib/aptible/cli/subcommands/backup.rb +22 -4
- data/lib/aptible/cli/subcommands/config.rb +15 -11
- data/lib/aptible/cli/subcommands/db.rb +82 -31
- data/lib/aptible/cli/subcommands/deploy.rb +1 -1
- data/lib/aptible/cli/subcommands/endpoints.rb +11 -8
- data/lib/aptible/cli/subcommands/operation.rb +2 -1
- data/lib/aptible/cli/subcommands/rebuild.rb +1 -1
- data/lib/aptible/cli/subcommands/restart.rb +1 -1
- data/lib/aptible/cli/subcommands/services.rb +8 -9
- data/lib/aptible/cli/version.rb +1 -1
- data/spec/aptible/cli/agent_spec.rb +11 -14
- data/spec/aptible/cli/formatter_spec.rb +4 -0
- data/spec/aptible/cli/renderer/json_spec.rb +63 -0
- data/spec/aptible/cli/renderer/text_spec.rb +150 -0
- data/spec/aptible/cli/resource_formatter_spec.rb +113 -0
- data/spec/aptible/cli/subcommands/apps_spec.rb +144 -28
- data/spec/aptible/cli/subcommands/backup_spec.rb +37 -16
- data/spec/aptible/cli/subcommands/config_spec.rb +95 -0
- data/spec/aptible/cli/subcommands/db_spec.rb +185 -93
- data/spec/aptible/cli/subcommands/endpoints_spec.rb +10 -8
- data/spec/aptible/cli/subcommands/operation_spec.rb +0 -1
- data/spec/aptible/cli/subcommands/rebuild_spec.rb +17 -0
- data/spec/aptible/cli/subcommands/services_spec.rb +8 -12
- data/spec/aptible/cli_spec.rb +31 -0
- data/spec/fabricators/account_fabricator.rb +11 -0
- data/spec/fabricators/app_fabricator.rb +15 -0
- data/spec/fabricators/configuration_fabricator.rb +8 -0
- data/spec/fabricators/database_image_fabricator.rb +17 -0
- data/spec/fabricators/operation_fabricator.rb +1 -0
- data/spec/fabricators/service_fabricator.rb +4 -0
- data/spec/spec_helper.rb +63 -1
- metadata +55 -4
- data/spec/aptible/cli/helpers/vhost_spec.rb +0 -105
@@ -4,10 +4,12 @@ class SocatHelperMock < OpenStruct
|
|
4
4
|
end
|
5
5
|
|
6
6
|
describe Aptible::CLI::Agent do
|
7
|
+
let(:token) { double('token') }
|
8
|
+
|
7
9
|
before do
|
8
10
|
allow(subject).to receive(:ask)
|
9
11
|
allow(subject).to receive(:save_token)
|
10
|
-
allow(subject).to receive(:fetch_token) {
|
12
|
+
allow(subject).to receive(:fetch_token) { token }
|
11
13
|
end
|
12
14
|
|
13
15
|
let(:handle) { 'foobar' }
|
@@ -15,79 +17,114 @@ describe Aptible::CLI::Agent do
|
|
15
17
|
let(:socat_helper) { SocatHelperMock.new(port: 4242) }
|
16
18
|
|
17
19
|
describe '#db:create' do
|
18
|
-
let(:db) { Fabricate(:database) }
|
19
|
-
let(:op) { Fabricate(:operation) }
|
20
|
-
let(:account) { Fabricate(:account) }
|
21
|
-
|
22
20
|
before do
|
23
21
|
allow(Aptible::Api::Account).to receive(:all).and_return([account])
|
24
|
-
allow(db).to receive(:reload).and_return(db)
|
25
|
-
allow(op).to receive(:errors).and_return(Aptible::Resource::Errors.new)
|
26
22
|
end
|
27
23
|
|
28
|
-
|
24
|
+
def expect_provision_database(create_opts, provision_opts = {})
|
25
|
+
db = Fabricate(:database)
|
26
|
+
expect(db).to receive(:reload).and_return(db)
|
27
|
+
|
28
|
+
op = Fabricate(:operation)
|
29
|
+
|
29
30
|
expect(account).to receive(:create_database!)
|
30
|
-
.with(
|
31
|
-
.and_return(db)
|
31
|
+
.with(**create_opts).and_return(db)
|
32
32
|
|
33
33
|
expect(db).to receive(:create_operation)
|
34
|
-
.with(type: 'provision')
|
35
|
-
|
34
|
+
.with(type: 'provision', **provision_opts).and_return(op)
|
35
|
+
|
36
|
+
expect(subject).to receive(:attach_to_operation_logs).with(op)
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:account) { Fabricate(:account) }
|
36
40
|
|
37
|
-
|
38
|
-
|
41
|
+
it 'creates a new DB' do
|
42
|
+
expect_provision_database(handle: 'foo', type: 'postgresql')
|
39
43
|
|
40
44
|
subject.options = { type: 'postgresql' }
|
41
45
|
subject.send('db:create', 'foo')
|
42
46
|
end
|
43
47
|
|
44
48
|
it 'creates a new DB with a container size' do
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
expect(db).to receive(:create_operation)
|
50
|
-
.with(type: 'provision', container_size: 1024)
|
51
|
-
.and_return(op)
|
52
|
-
|
53
|
-
expect(subject).to receive(:attach_to_operation_logs)
|
54
|
-
.with(op)
|
49
|
+
expect_provision_database(
|
50
|
+
{ handle: 'foo', type: 'postgresql', initial_container_size: 1024 },
|
51
|
+
{ container_size: 1024 }
|
52
|
+
)
|
55
53
|
|
56
54
|
subject.options = { type: 'postgresql', container_size: 1024 }
|
57
55
|
subject.send('db:create', 'foo')
|
58
56
|
end
|
59
57
|
|
60
58
|
it 'creates a new DB with a disk size' do
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
expect(db).to receive(:create_operation)
|
66
|
-
.with(type: 'provision', disk_size: 200)
|
67
|
-
.and_return(op)
|
68
|
-
|
69
|
-
expect(subject).to receive(:attach_to_operation_logs)
|
70
|
-
.with(op)
|
59
|
+
expect_provision_database(
|
60
|
+
{ handle: 'foo', type: 'postgresql', initial_disk_size: 200 },
|
61
|
+
{ disk_size: 200 }
|
62
|
+
)
|
71
63
|
|
72
64
|
subject.options = { type: 'postgresql', size: 200 }
|
73
65
|
subject.send('db:create', 'foo')
|
74
66
|
end
|
75
67
|
|
76
68
|
it 'deprovisions the database if the operation cannot be created' do
|
77
|
-
|
69
|
+
db = Fabricate(:database)
|
70
|
+
|
71
|
+
provision_op = Fabricate(:operation)
|
72
|
+
provision_op.errors.full_messages << 'oops'
|
73
|
+
|
74
|
+
deprovision_op = Fabricate(:operation)
|
78
75
|
|
79
76
|
expect(account).to receive(:create_database!).and_return(db)
|
80
77
|
|
81
78
|
expect(db).to receive(:create_operation)
|
82
|
-
.with(type: 'provision')
|
83
|
-
.once.ordered.and_return(op)
|
79
|
+
.with(type: 'provision').once.ordered.and_return(provision_op)
|
84
80
|
|
85
81
|
expect(db).to receive(:create_operation!)
|
86
|
-
.with(type: 'deprovision')
|
87
|
-
.once.ordered
|
82
|
+
.with(type: 'deprovision').once.ordered.and_return(deprovision_op)
|
88
83
|
|
89
84
|
expect { subject.send('db:create', 'foo') }.to raise_error(/oops/im)
|
90
85
|
end
|
86
|
+
|
87
|
+
context 'with version' do
|
88
|
+
let(:img) do
|
89
|
+
Fabricate(:database_image, type: 'postgresql', version: '9.4')
|
90
|
+
end
|
91
|
+
|
92
|
+
let(:alt_version) do
|
93
|
+
Fabricate(:database_image, type: 'postgresql', version: '10')
|
94
|
+
end
|
95
|
+
|
96
|
+
let(:alt_type) do
|
97
|
+
Fabricate(:database_image, type: 'redis', version: '9.4')
|
98
|
+
end
|
99
|
+
|
100
|
+
before do
|
101
|
+
allow(Aptible::Api::DatabaseImage).to receive(:all)
|
102
|
+
.with(token: token).and_return([alt_version, alt_type, img])
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'provisions a Database with a matching Database Image' do
|
106
|
+
expect_provision_database(
|
107
|
+
handle: 'foo',
|
108
|
+
type: 'postgresql',
|
109
|
+
database_image: img
|
110
|
+
)
|
111
|
+
|
112
|
+
subject.options = { type: 'postgresql', version: '9.4' }
|
113
|
+
subject.send('db:create', 'foo')
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'fails if the Database Image does not exist' do
|
117
|
+
subject.options = { type: 'postgresql', version: '123' }
|
118
|
+
expect { subject.send('db:create', 'foo') }
|
119
|
+
.to raise_error(Thor::Error, /no database image/i)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'fails if type is not passed' do
|
123
|
+
subject.options = { version: '123' }
|
124
|
+
expect { subject.send('db:create', 'foo') }
|
125
|
+
.to raise_error(Thor::Error, /type is required/i)
|
126
|
+
end
|
127
|
+
end
|
91
128
|
end
|
92
129
|
|
93
130
|
describe '#db:tunnel' do
|
@@ -108,17 +145,20 @@ describe Aptible::CLI::Agent do
|
|
108
145
|
expect(subject).to receive(:with_local_tunnel).with(cred, 0)
|
109
146
|
.and_yield(socat_helper)
|
110
147
|
|
111
|
-
|
112
|
-
.with('Creating foo tunnel to foobar...', :green)
|
148
|
+
subject.send('db:tunnel', handle)
|
113
149
|
|
114
150
|
local_url = 'postgresql://aptible:password@localhost.aptible.in:4242/db'
|
115
|
-
expect(subject).to receive(:say)
|
116
|
-
.with("Connect at #{local_url}", :green)
|
117
151
|
|
118
|
-
|
119
|
-
|
120
|
-
expect(
|
121
|
-
|
152
|
+
expect(captured_logs)
|
153
|
+
.to match(/creating foo tunnel to foobar/i)
|
154
|
+
expect(captured_logs)
|
155
|
+
.to match(/connect at #{Regexp.escape(local_url)}/i)
|
156
|
+
|
157
|
+
expect(captured_logs).to match(/host: localhost\.aptible\.in/i)
|
158
|
+
expect(captured_logs).to match(/port: 4242/i)
|
159
|
+
expect(captured_logs).to match(/username: aptible/i)
|
160
|
+
expect(captured_logs).to match(/password: password/i)
|
161
|
+
expect(captured_logs).to match(/database: db/i)
|
122
162
|
end
|
123
163
|
|
124
164
|
it 'defaults to a default credential' do
|
@@ -126,14 +166,12 @@ describe Aptible::CLI::Agent do
|
|
126
166
|
Fabricate(:database_credential, database: database, type: 'foo')
|
127
167
|
Fabricate(:database_credential, database: database, type: 'bar')
|
128
168
|
|
129
|
-
messages = []
|
130
|
-
allow(subject).to receive(:say) { |m, *| messages << m }
|
131
169
|
expect(subject).to receive(:with_local_tunnel).with(ok, 0)
|
132
170
|
|
133
171
|
subject.send('db:tunnel', handle)
|
134
172
|
|
135
|
-
expect(
|
136
|
-
expect(
|
173
|
+
expect(captured_logs).to match(/use --type type/i)
|
174
|
+
expect(captured_logs).to match(/valid types.*foo.*bar/i)
|
137
175
|
end
|
138
176
|
|
139
177
|
it 'supports --type' do
|
@@ -143,7 +181,6 @@ describe Aptible::CLI::Agent do
|
|
143
181
|
ok = Fabricate(:database_credential, type: 'foo', database: database)
|
144
182
|
Fabricate(:database_credential, type: 'bar', database: database)
|
145
183
|
|
146
|
-
allow(subject).to receive(:say)
|
147
184
|
expect(subject).to receive(:with_local_tunnel).with(ok, 0)
|
148
185
|
subject.send('db:tunnel', handle)
|
149
186
|
end
|
@@ -174,7 +211,6 @@ describe Aptible::CLI::Agent do
|
|
174
211
|
context 'v1 stack' do
|
175
212
|
before do
|
176
213
|
allow(database.account.stack).to receive(:version) { 'v1' }
|
177
|
-
allow(subject).to receive(:say)
|
178
214
|
end
|
179
215
|
|
180
216
|
it 'falls back to the database itself if no type is given' do
|
@@ -199,13 +235,11 @@ describe Aptible::CLI::Agent do
|
|
199
235
|
end
|
200
236
|
|
201
237
|
it 'does not suggest other types that do not exist' do
|
202
|
-
messages = []
|
203
|
-
allow(subject).to receive(:say) { |m, *| messages << m }
|
204
238
|
expect(subject).to receive(:with_local_tunnel).with(database, 0)
|
205
239
|
|
206
240
|
subject.send('db:tunnel', handle)
|
207
241
|
|
208
|
-
expect(
|
242
|
+
expect(captured_logs).not_to match(/use --type type/i)
|
209
243
|
end
|
210
244
|
end
|
211
245
|
end
|
@@ -216,9 +250,14 @@ describe Aptible::CLI::Agent do
|
|
216
250
|
staging = Fabricate(:account, handle: 'staging')
|
217
251
|
prod = Fabricate(:account, handle: 'production')
|
218
252
|
|
219
|
-
[
|
220
|
-
|
221
|
-
|
253
|
+
[
|
254
|
+
[staging, 'staging-redis-db'],
|
255
|
+
[staging, 'staging-postgres-db'],
|
256
|
+
[prod, 'prod-elsearch-db'],
|
257
|
+
[prod, 'prod-postgres-db']
|
258
|
+
].each do |a, h|
|
259
|
+
d = Fabricate(:database, account: a, handle: h)
|
260
|
+
Fabricate(:database_credential, database: d)
|
222
261
|
end
|
223
262
|
|
224
263
|
token = 'the-token'
|
@@ -229,45 +268,38 @@ describe Aptible::CLI::Agent do
|
|
229
268
|
|
230
269
|
context 'when no account is specified' do
|
231
270
|
it 'prints out the grouped database handles for all accounts' do
|
232
|
-
allow(subject).to receive(:say)
|
233
|
-
|
234
271
|
subject.send('db:list')
|
235
272
|
|
236
|
-
expect(
|
237
|
-
expect(
|
238
|
-
expect(
|
273
|
+
expect(captured_output_text).to include('=== staging')
|
274
|
+
expect(captured_output_text).to include('staging-redis-db')
|
275
|
+
expect(captured_output_text).to include('staging-postgres-db')
|
239
276
|
|
240
|
-
expect(
|
241
|
-
expect(
|
242
|
-
expect(
|
277
|
+
expect(captured_output_text).to include('=== production')
|
278
|
+
expect(captured_output_text).to include('prod-elsearch-db')
|
279
|
+
expect(captured_output_text).to include('prod-postgres-db')
|
243
280
|
end
|
244
281
|
end
|
245
282
|
|
246
283
|
context 'when a valid account is specified' do
|
247
284
|
it 'prints out the database handles for the account' do
|
248
|
-
allow(subject).to receive(:say)
|
249
|
-
|
250
285
|
subject.options = { environment: 'staging' }
|
251
286
|
subject.send('db:list')
|
252
287
|
|
253
|
-
expect(
|
254
|
-
expect(
|
255
|
-
expect(
|
288
|
+
expect(captured_output_text).to include('=== staging')
|
289
|
+
expect(captured_output_text).to include('staging-redis-db')
|
290
|
+
expect(captured_output_text).to include('staging-postgres-db')
|
256
291
|
|
257
|
-
expect(
|
258
|
-
expect(
|
259
|
-
expect(
|
292
|
+
expect(captured_output_text).not_to include('=== production')
|
293
|
+
expect(captured_output_text).not_to include('prod-elsearch-db')
|
294
|
+
expect(captured_output_text).not_to include('prod-postgres-db')
|
260
295
|
end
|
261
296
|
end
|
262
297
|
|
263
298
|
context 'when an invalid account is specified' do
|
264
299
|
it 'prints out an error' do
|
265
|
-
allow(subject).to receive(:say)
|
266
|
-
|
267
300
|
subject.options = { environment: 'foo' }
|
268
|
-
expect { subject.send('db:list') }
|
269
|
-
'Specified account does not exist'
|
270
|
-
)
|
301
|
+
expect { subject.send('db:list') }
|
302
|
+
.to raise_error('Specified account does not exist')
|
271
303
|
end
|
272
304
|
end
|
273
305
|
end
|
@@ -281,10 +313,11 @@ describe Aptible::CLI::Agent do
|
|
281
313
|
it 'allows creating a new backup' do
|
282
314
|
expect(database).to receive(:create_operation!)
|
283
315
|
.with(type: 'backup').and_return(op)
|
284
|
-
expect(subject).to receive(:say).with('Backing up foobar...')
|
285
316
|
expect(subject).to receive(:attach_to_operation_logs).with(op)
|
286
317
|
|
287
318
|
subject.send('db:backup', handle)
|
319
|
+
|
320
|
+
expect(captured_logs).to match(/backing up foobar/i)
|
288
321
|
end
|
289
322
|
|
290
323
|
it 'fails if the DB is not found' do
|
@@ -302,10 +335,11 @@ describe Aptible::CLI::Agent do
|
|
302
335
|
it 'allows reloading a database' do
|
303
336
|
expect(database).to receive(:create_operation!)
|
304
337
|
.with(type: 'reload').and_return(op)
|
305
|
-
expect(subject).to receive(:say).with('Reloading foobar...')
|
306
338
|
expect(subject).to receive(:attach_to_operation_logs).with(op)
|
307
339
|
|
308
340
|
subject.send('db:reload', handle)
|
341
|
+
|
342
|
+
expect(captured_logs).to match(/reloading foobar/i)
|
309
343
|
end
|
310
344
|
|
311
345
|
it 'fails if the DB is not found' do
|
@@ -324,32 +358,35 @@ describe Aptible::CLI::Agent do
|
|
324
358
|
expect(database).to receive(:create_operation!)
|
325
359
|
.with(type: 'restart').and_return(op)
|
326
360
|
|
327
|
-
expect(subject).to receive(:say).with('Restarting foobar...')
|
328
361
|
expect(subject).to receive(:attach_to_operation_logs).with(op)
|
329
362
|
|
330
363
|
subject.send('db:restart', handle)
|
364
|
+
|
365
|
+
expect(captured_logs).to match(/restarting foobar/i)
|
331
366
|
end
|
332
367
|
|
333
368
|
it 'allows restarting a database with a container size' do
|
334
369
|
expect(database).to receive(:create_operation!)
|
335
370
|
.with(type: 'restart', container_size: 40).and_return(op)
|
336
371
|
|
337
|
-
expect(subject).to receive(:say).with('Restarting foobar...')
|
338
372
|
expect(subject).to receive(:attach_to_operation_logs).with(op)
|
339
373
|
|
340
374
|
subject.options = { container_size: 40 }
|
341
375
|
subject.send('db:restart', handle)
|
376
|
+
|
377
|
+
expect(captured_logs).to match(/restarting foobar/i)
|
342
378
|
end
|
343
379
|
|
344
380
|
it 'allows restarting a database with a disk size' do
|
345
381
|
expect(database).to receive(:create_operation!)
|
346
382
|
.with(type: 'restart', disk_size: 40).and_return(op)
|
347
383
|
|
348
|
-
expect(subject).to receive(:say).with('Restarting foobar...')
|
349
384
|
expect(subject).to receive(:attach_to_operation_logs).with(op)
|
350
385
|
|
351
386
|
subject.options = { size: 40 }
|
352
387
|
subject.send('db:restart', handle)
|
388
|
+
|
389
|
+
expect(captured_logs).to match(/restarting foobar/i)
|
353
390
|
end
|
354
391
|
|
355
392
|
it 'fails if the DB is not found' do
|
@@ -369,13 +406,12 @@ describe Aptible::CLI::Agent do
|
|
369
406
|
|
370
407
|
context 'valid database' do
|
371
408
|
it 'returns the URL of a specified DB' do
|
372
|
-
cred = Fabricate(
|
373
|
-
|
374
|
-
|
375
|
-
expect(subject).to receive(:say).with(cred.connection_url)
|
409
|
+
cred = Fabricate(
|
410
|
+
:database_credential, default: true, type: 'foo', database: database
|
411
|
+
)
|
376
412
|
expect(database).not_to receive(:connection_url)
|
377
|
-
|
378
413
|
subject.send('db:url', handle)
|
414
|
+
expect(captured_output_text.chomp).to eq(cred.connection_url)
|
379
415
|
end
|
380
416
|
|
381
417
|
it 'fails if multiple DBs are found' do
|
@@ -388,19 +424,75 @@ describe Aptible::CLI::Agent do
|
|
388
424
|
context 'v1 stack' do
|
389
425
|
before do
|
390
426
|
allow(database.account.stack).to receive(:version) { 'v1' }
|
391
|
-
allow(subject).to receive(:say)
|
392
427
|
end
|
393
428
|
|
394
429
|
it 'returns the URL of a specified DB' do
|
395
430
|
connection_url = 'postgresql://aptible-v1:password@lega.cy:4242/db'
|
396
|
-
|
397
|
-
expect(subject).to receive(:say).with(connection_url)
|
398
431
|
expect(database).to receive(:connection_url)
|
399
432
|
.and_return(connection_url)
|
400
433
|
|
401
434
|
subject.send('db:url', handle)
|
435
|
+
|
436
|
+
expect(captured_output_text.chomp).to eq(connection_url)
|
402
437
|
end
|
403
438
|
end
|
404
439
|
end
|
405
440
|
end
|
441
|
+
|
442
|
+
describe '#db:deprovision' do
|
443
|
+
before { expect(Aptible::Api::Database).to receive(:all) { [database] } }
|
444
|
+
|
445
|
+
let(:operation) { Fabricate(:operation, resource: database) }
|
446
|
+
|
447
|
+
it 'deprovisions a database' do
|
448
|
+
expect(database).to receive(:create_operation!)
|
449
|
+
.with(type: 'deprovision').and_return(operation)
|
450
|
+
|
451
|
+
expect(subject).not_to receive(:attach_to_operation_logs)
|
452
|
+
|
453
|
+
subject.send('db:deprovision', handle)
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
describe '#db:versions' do
|
458
|
+
let(:token) { double('token') }
|
459
|
+
|
460
|
+
before do
|
461
|
+
allow(subject).to receive(:save_token)
|
462
|
+
allow(subject).to receive(:fetch_token) { token }
|
463
|
+
end
|
464
|
+
|
465
|
+
let(:i1) do
|
466
|
+
Fabricate(:database_image, type: 'postgresql', version: '9.4')
|
467
|
+
end
|
468
|
+
|
469
|
+
let(:i2) do
|
470
|
+
Fabricate(:database_image, type: 'postgresql', version: '10')
|
471
|
+
end
|
472
|
+
|
473
|
+
let(:i3) do
|
474
|
+
Fabricate(:database_image, type: 'redis', version: '3.0')
|
475
|
+
end
|
476
|
+
|
477
|
+
before do
|
478
|
+
allow(Aptible::Api::DatabaseImage).to receive(:all)
|
479
|
+
.with(token: token).and_return([i1, i2, i3])
|
480
|
+
end
|
481
|
+
|
482
|
+
it 'lists grouped existing Database versions' do
|
483
|
+
subject.send('db:versions')
|
484
|
+
|
485
|
+
expected = [
|
486
|
+
'=== postgresql',
|
487
|
+
'9.4',
|
488
|
+
'10',
|
489
|
+
'',
|
490
|
+
'=== redis',
|
491
|
+
'3.0',
|
492
|
+
''
|
493
|
+
].join("\n")
|
494
|
+
|
495
|
+
expect(captured_output_text).to eq(expected)
|
496
|
+
end
|
497
|
+
end
|
406
498
|
end
|