ey_cli 0.1.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.
- data/Gemfile +3 -0
- data/Gemfile.lock +57 -0
- data/LICENSE +22 -0
- data/README.md +104 -0
- data/Rakefile +129 -0
- data/bin/ey_cli +5 -0
- data/ey_cli.gemspec +117 -0
- data/history.md +3 -0
- data/lib/ey_cli/api.rb +96 -0
- data/lib/ey_cli/cli.rb +17 -0
- data/lib/ey_cli/command_manager.rb +29 -0
- data/lib/ey_cli/commands/accounts.rb +26 -0
- data/lib/ey_cli/commands/apps.rb +24 -0
- data/lib/ey_cli/commands/base.rb +16 -0
- data/lib/ey_cli/commands/console.rb +38 -0
- data/lib/ey_cli/commands/create_app.rb +76 -0
- data/lib/ey_cli/commands/create_env.rb +106 -0
- data/lib/ey_cli/commands/deploy.rb +23 -0
- data/lib/ey_cli/commands/help.rb +65 -0
- data/lib/ey_cli/commands/show.rb +65 -0
- data/lib/ey_cli/controllers/accounts.rb +23 -0
- data/lib/ey_cli/controllers/apps.rb +66 -0
- data/lib/ey_cli/controllers/environments.rb +78 -0
- data/lib/ey_cli/git_utils.rb +12 -0
- data/lib/ey_cli/models/account.rb +6 -0
- data/lib/ey_cli/models/app.rb +15 -0
- data/lib/ey_cli/models/base.rb +54 -0
- data/lib/ey_cli/models/environment.rb +32 -0
- data/lib/ey_cli/options_parser.rb +47 -0
- data/lib/ey_cli/smarty_parser.rb +29 -0
- data/lib/ey_cli/term.rb +58 -0
- data/lib/ey_cli.rb +46 -0
- data/spec/auth_helper.rb +28 -0
- data/spec/ey_cli/api_spec.rb +70 -0
- data/spec/ey_cli/command_manager_spec.rb +33 -0
- data/spec/ey_cli/commands/help_spec.rb +36 -0
- data/spec/ey_cli/controllers/accounts_spec.rb +40 -0
- data/spec/ey_cli/controllers/apps_spec.rb +97 -0
- data/spec/ey_cli/controllers/environments_spec.rb +101 -0
- data/spec/ey_cli/models/app_spec.rb +50 -0
- data/spec/ey_cli/models/base_spec.rb +98 -0
- data/spec/ey_cli/models/environment_spec.rb +51 -0
- data/spec/ey_cli/options_parser_spec.rb +19 -0
- data/spec/ey_cli/smarty_parser_spec.rb +19 -0
- data/spec/spec_helper.rb +29 -0
- metadata +288 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
module EYCli
|
2
|
+
module SmartyParser
|
3
|
+
def parse(body, klass = self)
|
4
|
+
case body
|
5
|
+
when Hash
|
6
|
+
klass.new smarty(body)
|
7
|
+
when Array
|
8
|
+
body.map { |item| parse(item, klass) }
|
9
|
+
else
|
10
|
+
body
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def smarty(hash)
|
15
|
+
hash.each do |key, value|
|
16
|
+
case key
|
17
|
+
when /accounts?/
|
18
|
+
hash[key] = parse(value, EYCli::Model::Account)
|
19
|
+
when /apps?/
|
20
|
+
hash[key] = parse(value, EYCli::Model::App)
|
21
|
+
when /environments?/
|
22
|
+
hash[key] = parse(value, EYCli::Model::Environment)
|
23
|
+
else
|
24
|
+
hash[key] = parse(value, Hashie::Mash)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/ey_cli/term.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module EYCli
|
2
|
+
class Term
|
3
|
+
require 'highline'
|
4
|
+
|
5
|
+
attr_reader :terminal
|
6
|
+
|
7
|
+
def initialize(input = $stdin, output = $stdout)
|
8
|
+
HighLine.color_scheme = HighLine::SampleColorScheme.new
|
9
|
+
@terminal = HighLine.new(input, output)
|
10
|
+
end
|
11
|
+
|
12
|
+
def choose_resource(collection, message, prompt)
|
13
|
+
say(message)
|
14
|
+
|
15
|
+
terminal.choose do |menu|
|
16
|
+
menu.index = :number
|
17
|
+
menu.index_suffix = ' ~> '
|
18
|
+
menu.prompt = prompt
|
19
|
+
|
20
|
+
collection.each do |resource|
|
21
|
+
menu.choice resource.name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def say(message)
|
27
|
+
terminal.say(message)
|
28
|
+
end
|
29
|
+
|
30
|
+
def error(message)
|
31
|
+
terminal.say(%Q{<%= color("#{message}", :error)%>})
|
32
|
+
end
|
33
|
+
|
34
|
+
def warning(message)
|
35
|
+
terminal.say(%Q{<%= color("#{message}", :warning)%>})
|
36
|
+
end
|
37
|
+
|
38
|
+
def success(message)
|
39
|
+
terminal.say(%Q{<%= color("#{message}", :debug)%>})
|
40
|
+
end
|
41
|
+
|
42
|
+
def print_errors(errors, message)
|
43
|
+
error(message)
|
44
|
+
errors.each do |key, value|
|
45
|
+
alert = value.respond_to?(:join) ? value.join(',') : value.inspect
|
46
|
+
error("\t- #{key}: #{alert}")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def ask(prompt, protected_filed = false)
|
51
|
+
if protected_filed
|
52
|
+
terminal.ask(prompt) {|q| q.echo = '*'}
|
53
|
+
else
|
54
|
+
terminal.ask(prompt) {|q| q.readline = true}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/ey_cli.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module EYCli
|
2
|
+
VERSION = '0.1.0'
|
3
|
+
|
4
|
+
require 'hashie/mash'
|
5
|
+
require 'json'
|
6
|
+
require 'multi_json'
|
7
|
+
|
8
|
+
require 'ey_cli/api'
|
9
|
+
require 'ey_cli/cli'
|
10
|
+
require 'ey_cli/git_utils'
|
11
|
+
require 'ey_cli/command_manager'
|
12
|
+
require 'ey_cli/options_parser'
|
13
|
+
require 'ey_cli/smarty_parser'
|
14
|
+
require 'ey_cli/term'
|
15
|
+
|
16
|
+
require 'ey_cli/models/base'
|
17
|
+
require 'ey_cli/models/account'
|
18
|
+
require 'ey_cli/models/app'
|
19
|
+
require 'ey_cli/models/environment'
|
20
|
+
|
21
|
+
require 'ey_cli/controllers/accounts'
|
22
|
+
require 'ey_cli/controllers/apps'
|
23
|
+
require 'ey_cli/controllers/environments'
|
24
|
+
|
25
|
+
require 'ey_cli/commands/base'
|
26
|
+
require 'ey_cli/commands/accounts'
|
27
|
+
require 'ey_cli/commands/apps'
|
28
|
+
require 'ey_cli/commands/console'
|
29
|
+
require 'ey_cli/commands/create_app'
|
30
|
+
require 'ey_cli/commands/create_env'
|
31
|
+
require 'ey_cli/commands/deploy'
|
32
|
+
require 'ey_cli/commands/help'
|
33
|
+
require 'ey_cli/commands/show'
|
34
|
+
|
35
|
+
def self.api(endpoint = nil)
|
36
|
+
@api ||= Api.new(endpoint)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.term(input = $stdin, output = $stdout)
|
40
|
+
@ui ||= Term.new(input, output)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.command_manager
|
44
|
+
@command_manager ||= EYCli::CommandManager.new
|
45
|
+
end
|
46
|
+
end
|
data/spec/auth_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module EYCli
|
2
|
+
module AuthHelper
|
3
|
+
def self.extended(example_group)
|
4
|
+
example_group.use_credentials(example_group)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.included(example_group)
|
8
|
+
example_group.extend self
|
9
|
+
end
|
10
|
+
|
11
|
+
def mock_credentials
|
12
|
+
rc = File.expand_path('../fake_rc', __FILE__)
|
13
|
+
|
14
|
+
File.open(rc, 'w') do |f| f.write <<-EOF
|
15
|
+
---
|
16
|
+
api_token: fake_token
|
17
|
+
EOF
|
18
|
+
end
|
19
|
+
ENV['EYRC'] = rc
|
20
|
+
end
|
21
|
+
|
22
|
+
def use_credentials(describe_block)
|
23
|
+
describe_block.before :each do
|
24
|
+
mock_credentials
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe EYCli::Api do
|
4
|
+
subject { EYCli::Api.new('http://example.com') }
|
5
|
+
|
6
|
+
context "reading the auth token from the file" do
|
7
|
+
it "returns nil if the file doesn't exist" do
|
8
|
+
subject.read_token('fake_file').should be_nil
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns nil if the file is empty" do
|
12
|
+
File.open('fake_file', 'w')
|
13
|
+
subject.read_token('fake_file').should be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns the token in the root if there is no token for the endpoint" do
|
17
|
+
File.open('fake_file', 'w') do |f|
|
18
|
+
f.write <<-EOF
|
19
|
+
---
|
20
|
+
api_token: root_api_token
|
21
|
+
EOF
|
22
|
+
end
|
23
|
+
|
24
|
+
subject.read_token('fake_file').should == 'root_api_token'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns the token for the endpoint if exists" do
|
28
|
+
File.open('fake_file', 'w') do |f|
|
29
|
+
f.write <<-EOF
|
30
|
+
---
|
31
|
+
api_token: root_api_token
|
32
|
+
http://example.com:
|
33
|
+
api_token: example_com_api_token
|
34
|
+
EOF
|
35
|
+
end
|
36
|
+
|
37
|
+
subject.read_token('fake_file').should == 'example_com_api_token'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "saving the auth token" do
|
42
|
+
def fake_rc_file
|
43
|
+
File.read('fake_file').gsub(/\s*/m, '')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "stores the token under the enpoint" do
|
47
|
+
subject.save_token('new_token', 'fake_file')
|
48
|
+
fake_rc_file.should == '---http://example.com:api_token:new_token'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "adds it to the file if already existed" do
|
52
|
+
File.open('fake_file', 'w') {|f| f.write("---\n api_token: root_token") }
|
53
|
+
subject.save_token('new_token', 'fake_file')
|
54
|
+
fake_rc_file.should == '---api_token:root_tokenhttp://example.com:api_token:new_token'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "fetching the token from the terminal" do
|
59
|
+
it "sends the user credentials to the api" do
|
60
|
+
EYCli.term.should_receive(:ask).with('Email: ').and_return('foo@foo.com')
|
61
|
+
EYCli.term.should_receive(:ask).with('Password: ', true).and_return('fooooo')
|
62
|
+
|
63
|
+
stub_request(:post, "http://example.com/authenticate?email=foo@foo.com&password=fooooo").
|
64
|
+
to_return(:status => 200, :body => to_json(:api_token => 'foo_token'))
|
65
|
+
|
66
|
+
ENV['EYRC'] = 'fake_file'
|
67
|
+
subject.fetch_token.should == 'foo_token'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
module EYCli::Command
|
4
|
+
class MockCommand; end
|
5
|
+
end
|
6
|
+
|
7
|
+
describe EYCli::CommandManager do
|
8
|
+
before { subject.register_command(:mock_command) }
|
9
|
+
|
10
|
+
it "registers commands" do
|
11
|
+
subject.commands.keys.should include(:mock_command)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns nil if the command class is not registered" do
|
15
|
+
subject[:bar].should be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns an instance of the command class if it's registered" do
|
19
|
+
subject[:mock_command].should be_instance_of(EYCli::Command::MockCommand)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns nil if the command class is not defined" do
|
23
|
+
subject.register_command(:bar)
|
24
|
+
subject[:bar].should be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "only loads the command class once" do
|
28
|
+
subject.should_receive(:load_command).
|
29
|
+
with(:mock_command).
|
30
|
+
once.and_return(EYCli::Command::MockCommand.new)
|
31
|
+
subject[:mock_command] || subject[:mock_command]
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class EYCli::Command::WithoutHelp; def help; end end
|
4
|
+
class EYCli::Command::WithHelp; def help; 'run with_help' end end
|
5
|
+
|
6
|
+
describe EYCli::Command::Help do
|
7
|
+
before do
|
8
|
+
EYCli.command_manager.register_command :without_help
|
9
|
+
EYCli.command_manager.register_command :with_help
|
10
|
+
end
|
11
|
+
|
12
|
+
it "prints the global help when the command name is not provided" do
|
13
|
+
subject.run([])
|
14
|
+
$stdout_test.string.should =~ /ey_cli help commands/
|
15
|
+
end
|
16
|
+
|
17
|
+
it "says that the help is not available when the command does not exist" do
|
18
|
+
subject.run(['fake_command'])
|
19
|
+
$stdout_test.string.should =~ /help not available/
|
20
|
+
end
|
21
|
+
|
22
|
+
it "says that the help is not available when the command does not have any help message" do
|
23
|
+
subject.run(['without_help'])
|
24
|
+
$stdout_test.string.should =~ /help not available for command: 'without_help'/
|
25
|
+
end
|
26
|
+
|
27
|
+
it "shows the available commands" do
|
28
|
+
subject.run(['commands'])
|
29
|
+
$stdout_test.string.should =~ /available commands/
|
30
|
+
end
|
31
|
+
|
32
|
+
it "shows the help message for the specified command" do
|
33
|
+
subject.run(['with_help'])
|
34
|
+
$stdout_test.string.should =~ /run with_help/
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe EYCli::Controller::Accounts do
|
4
|
+
it "returns the first account if we don't provide a name and the user has only one account" do
|
5
|
+
expected = EYCli::Model::Account.new({:id => 1, :name => 'foo'})
|
6
|
+
stub_request(:get, 'http://example.com/accounts').
|
7
|
+
to_return(:status => 200, :body => to_json({'accounts' => [expected]}))
|
8
|
+
|
9
|
+
account = subject.fetch_account
|
10
|
+
account.should == expected
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns nil if we don't find the account by the name provided" do
|
14
|
+
expected = EYCli::Model::Account.new({:id => 1, :name => 'foo'})
|
15
|
+
stub_request(:get, 'http://example.com/accounts').
|
16
|
+
to_return(:status => 200, :body => to_json({'accounts' => [expected]}))
|
17
|
+
|
18
|
+
subject.fetch_account('bar').should be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns nil if the user hasn't created an account yet" do
|
22
|
+
stub_request(:get, 'http://example.com/accounts').
|
23
|
+
to_return(:status => 200, :body => to_json({'accounts' => []}))
|
24
|
+
|
25
|
+
subject.fetch_account.should be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns the account selected by the user" do
|
29
|
+
account1 = EYCli::Model::Account.new({:id => 1, :name => 'foo'})
|
30
|
+
account2 = EYCli::Model::Account.new({:id => 2, :name => 'bar'})
|
31
|
+
account3 = EYCli::Model::Account.new({:id => 3, :name => 'baz'})
|
32
|
+
stub_request(:get, 'http://example.com/accounts').
|
33
|
+
to_return(:status => 200, :body => to_json({'accounts' => [account1, account2, account3]}))
|
34
|
+
|
35
|
+
EYCli.term.terminal.should_receive(:choose).and_return('bar')
|
36
|
+
|
37
|
+
account = subject.fetch_account
|
38
|
+
account.should == account2
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe EYCli::Controller::Apps do
|
4
|
+
before { Dir.mkdir('fake_app') }
|
5
|
+
let(:account) { EYCli::Model::Account.new(:id => 1) }
|
6
|
+
|
7
|
+
it "shows an error message when the directory is not a git repository" do
|
8
|
+
EYCli.term.should_receive(:error).with('Not a git repository: fake_app')
|
9
|
+
subject.create(account, 'fake_app')
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'trying to figure out the application type' do
|
13
|
+
it "uses rails 3 as default" do
|
14
|
+
subject.fetch_type('fake_app').should == :rails3
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'is a rails 3 app if the directory has the environment and rackup files' do
|
18
|
+
Dir.mkdir('fake_app/config')
|
19
|
+
['fake_app/config.ru', 'fake_app/config/environment.rb'].each {|f| File.open(f, 'w')}
|
20
|
+
|
21
|
+
subject.fetch_type('fake_app').should == :rails3
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'is a rails 2 app if the directory only includes the environment file' do
|
25
|
+
Dir.mkdir('fake_app/config')
|
26
|
+
File.open('fake_app/config/environment.rb', 'w')
|
27
|
+
subject.fetch_type('fake_app').should == :rails2
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'is a rack app if the directory only includes the rackup file' do
|
31
|
+
File.open('fake_app/config.ru', 'w')
|
32
|
+
subject.fetch_type('fake_app').should == :rack
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'under a git repository' do
|
37
|
+
before { Dir.mkdir('fake_app/.git') }
|
38
|
+
let(:success_params) do
|
39
|
+
{
|
40
|
+
:account => account,
|
41
|
+
'app[name]' => 'fake_app',
|
42
|
+
'app[app_type_id]' => 'rails3',
|
43
|
+
'app[repository_uri]' => 'git@git.com:foo/bar.git'
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'shows an error if the model cannot create the application' do
|
48
|
+
app_with_errors = EYCli::Model::App.new({:errors => {:name => 'bad_name'}})
|
49
|
+
EYCli.term.should_receive(:print_errors).with(app_with_errors.errors, 'App creation failed:')
|
50
|
+
EYCli::Model::App.should_receive(:create).and_return(app_with_errors)
|
51
|
+
|
52
|
+
subject.create(account, 'fake_app')
|
53
|
+
end
|
54
|
+
|
55
|
+
it "shows a success message when the model creates the app" do
|
56
|
+
app = EYCli::Model::App.new({:id => 1, :name => 'fake_app'})
|
57
|
+
EYCli::Model::App.should_receive(:create).with(success_params).and_return(app)
|
58
|
+
EYCli.term.should_receive(:success)
|
59
|
+
subject.should_receive(:fetch_repository).and_return('git@git.com:foo/bar.git')
|
60
|
+
|
61
|
+
subject.create(account, 'fake_app')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context '#fetch_app' do
|
66
|
+
let(:app1) { EYCli::Model::App.new(:id => 1, :repository_uri => 'git@foo.com', :name => 'foo_app') }
|
67
|
+
let(:app2) { EYCli::Model::App.new(:id => 2, :repository_uri => 'git@bar.com', :name => 'bar_app') }
|
68
|
+
|
69
|
+
it 'returns the first app if the user only has one' do
|
70
|
+
stub_request(:get, 'http://example.com/apps').
|
71
|
+
to_return(:status => 200, :body => to_json(:apps => [app1]))
|
72
|
+
subject.fetch_app.should == app1
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns the first app that matches the name passed as an option' do
|
76
|
+
stub_request(:get, 'http://example.com/apps').
|
77
|
+
to_return(:status => 200, :body => to_json(:apps => [app1, app2]))
|
78
|
+
subject.fetch_app(nil, {:app_name => 'bar_app'}).should == app2
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'returns the first app that matches the git repository uri of the base path' do
|
82
|
+
stub_request(:get, 'http://example.com/apps').
|
83
|
+
to_return(:status => 200, :body => to_json(:apps => [app1, app2]))
|
84
|
+
subject.should_receive(:git_repository?).and_return(true)
|
85
|
+
subject.should_receive(:fetch_repository).and_return('git@bar.com')
|
86
|
+
|
87
|
+
subject.fetch_app.should == app2
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'returns the app according to the option the user chooses' do
|
91
|
+
stub_request(:get, 'http://example.com/apps').
|
92
|
+
to_return(:status => 200, :body => to_json(:apps => [app1, app2]))
|
93
|
+
EYCli.term.should_receive(:choose_resource).and_return('bar_app')
|
94
|
+
subject.fetch_app.should == app2
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe EYCli::Controller::Environments do
|
4
|
+
let(:app) { EYCli::Model::App.new(:id => 1, :name => 'fake_app') }
|
5
|
+
|
6
|
+
context 'creating a new environment' do
|
7
|
+
let(:success_params) do
|
8
|
+
{
|
9
|
+
:app => app,
|
10
|
+
'environment[name]' => "#{app.name}_production",
|
11
|
+
'environment[framework_env]' => 'production',
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
it "shows an error message if the model cannot create the environment" do
|
16
|
+
env_with_errors = EYCli::Model::Environment.new({:errors => {:name => 'bad_name'}})
|
17
|
+
EYCli.term.should_receive(:print_errors).with(env_with_errors.errors, 'Environment creation failed:')
|
18
|
+
EYCli::Model::Environment.should_receive(:create).and_return(env_with_errors)
|
19
|
+
|
20
|
+
subject.create(app, {})
|
21
|
+
end
|
22
|
+
|
23
|
+
it "shows a success message when the model creates the app" do
|
24
|
+
env = EYCli::Model::Environment.new({:id => 1, :name => 'fake_app_production', :framework_env => 'production'})
|
25
|
+
EYCli::Model::Environment.should_receive(:create).with(success_params).and_return(env)
|
26
|
+
EYCli.term.should_receive(:success)
|
27
|
+
|
28
|
+
response = subject.create(app, {})
|
29
|
+
response.should == env
|
30
|
+
end
|
31
|
+
|
32
|
+
it "allows to specify the framework environment as a parameter" do
|
33
|
+
params = success_params.merge({'environment[name]' => 'fake_app_staging', 'environment[framework_env]' => 'staging'})
|
34
|
+
env = EYCli::Model::Environment.new({:id => 1, :name => 'fake_app_staging', :framework_env => 'staging'})
|
35
|
+
EYCli::Model::Environment.should_receive(:create).with(params).and_return(env)
|
36
|
+
EYCli.term.should_receive(:success)
|
37
|
+
|
38
|
+
response = subject.create(app, {:framework_env => 'staging'})
|
39
|
+
response.should == env
|
40
|
+
end
|
41
|
+
|
42
|
+
it "allows to specify the environment name" do
|
43
|
+
params = success_params.merge({'environment[name]' => 'fake_environment_name', 'environment[framework_env]' => 'production'})
|
44
|
+
env = EYCli::Model::Environment.new({:id => 1, :name => 'fake_environment_name', :framework_env => 'production'})
|
45
|
+
EYCli::Model::Environment.should_receive(:create).with(params).and_return(env)
|
46
|
+
EYCli.term.should_receive(:success)
|
47
|
+
|
48
|
+
response = subject.create(app, {:name => 'fake_environment_name'})
|
49
|
+
response.should == env
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with cluster options" do
|
53
|
+
it "is pending"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "deploying an environment" do
|
58
|
+
it "shows an error if the application doesn't have any environment" do
|
59
|
+
EYCli.term.should_receive(:error)
|
60
|
+
subject.deploy(app)
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when the app has only one environment" do
|
64
|
+
before do
|
65
|
+
@env = mock
|
66
|
+
app[:environments] = [@env]
|
67
|
+
end
|
68
|
+
|
69
|
+
it "uses the environment without asking" do
|
70
|
+
@env.should_receive(:deploy).and_return(Hashie::Mash.new)
|
71
|
+
EYCli.term.should_not_receive(:choose_resource)
|
72
|
+
subject.deploy(app)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "shows the error list when the deploy fails" do
|
76
|
+
expected = Hashie::Mash.new({:errors => {:provision => 'Amazon cannot provision the instance'}})
|
77
|
+
@env.should_receive(:deploy).and_return(expected)
|
78
|
+
EYCli.term.should_receive(:print_errors).with(expected.errors, "Application deployment failed:")
|
79
|
+
subject.deploy(app)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "shows the success message if it doesn't return any error" do
|
83
|
+
@env.should_receive(:deploy).and_return(Hashie::Mash.new)
|
84
|
+
EYCli.term.should_receive(:success)
|
85
|
+
subject.deploy(app)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when the app has more than one environment" do
|
90
|
+
it "shows the environments' list to let the user choose" do
|
91
|
+
env1 = EYCli::Model::Environment.new(:name => 'mock1')
|
92
|
+
env2 = mock
|
93
|
+
env2.should_receive(:name).and_return('mock2')
|
94
|
+
env2.should_receive(:deploy).and_return(Hashie::Mash.new)
|
95
|
+
app[:environments] = [env1, env2]
|
96
|
+
EYCli.term.should_receive(:choose_resource).and_return('mock2')
|
97
|
+
subject.deploy(app)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe EYCli::Model::App do
|
4
|
+
context ".create" do
|
5
|
+
it "return an error if it doesn't find the account" do
|
6
|
+
app = EYCli::Model::App.create({})
|
7
|
+
app.errors?.should be_true
|
8
|
+
app.errors.keys.should include('account')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "return an error if a model validation fails" do
|
12
|
+
account = EYCli::Model::Account.new({:id => 1})
|
13
|
+
stub_request(:post, 'http://example.com/accounts/1/apps?app[name]=foo').
|
14
|
+
to_return(:status => 422, :body => to_json({:errors => {:name => ['App name already exists']}}))
|
15
|
+
|
16
|
+
app = EYCli::Model::App.create({:account => account, 'app[name]' => 'foo'})
|
17
|
+
app.errors?.should be_true
|
18
|
+
app.errors.keys.should include('name')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns the new app when it's successful" do
|
22
|
+
account = EYCli::Model::Account.new({:id => 1})
|
23
|
+
expected = EYCli::Model::App.new({:id => 1, :name => 'foo'})
|
24
|
+
stub_request(:post, 'http://example.com/accounts/1/apps?app[name]=foo').
|
25
|
+
to_return(:status => 201, :body => to_json(:app => expected))
|
26
|
+
|
27
|
+
app = EYCli::Model::App.create({:account => account, 'app[name]' => 'foo'})
|
28
|
+
app.should == expected
|
29
|
+
end
|
30
|
+
|
31
|
+
context '.find_by_repository_uri' do
|
32
|
+
let(:app1) { EYCli::Model::App.new(:id => 1, :repository_uri => 'git@foo.com') }
|
33
|
+
let(:app2) { EYCli::Model::App.new(:id => 2, :repository_uri => 'git@bar.com') }
|
34
|
+
before do
|
35
|
+
stub_request(:get, 'http://example.com/apps').
|
36
|
+
to_return(:status => 200, :body => to_json(:apps => [app1, app2]))
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns an instance of App if it finds it" do
|
40
|
+
app = EYCli::Model::App.find_by_repository_uri('git@bar.com')
|
41
|
+
app.should == app2
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns nil when it cannot find the app" do
|
45
|
+
app = EYCli::Model::App.find_by_repository_uri('foo@bar.com')
|
46
|
+
app.should be_nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|