webbynode 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of webbynode might be problematic. Click here for more details.

Files changed (98) hide show
  1. data/Manifest +88 -4
  2. data/PostInstall.txt +42 -9
  3. data/README.rdoc +6 -0
  4. data/Rakefile +16 -19
  5. data/assets/webbynode.png +0 -0
  6. data/bin/webbynode +3 -3
  7. data/bin/wn +7 -0
  8. data/cucumber.yml +1 -0
  9. data/devver.rake +174 -0
  10. data/features/bootstrap.feature +17 -0
  11. data/features/step_definitions/command_steps.rb +14 -0
  12. data/features/support/env.rb +22 -0
  13. data/features/support/hooks.rb +8 -0
  14. data/{test/test_webbynode.rb → features/support/io_features.rb} +0 -0
  15. data/features/support/mocha.rb +15 -0
  16. data/lib/templates/api_token +14 -0
  17. data/lib/templates/backup +15 -0
  18. data/lib/templates/gitignore +4 -0
  19. data/lib/templates/help +53 -0
  20. data/lib/webbynode/api_client.rb +121 -0
  21. data/lib/webbynode/application.rb +21 -0
  22. data/lib/webbynode/command.rb +332 -0
  23. data/lib/webbynode/commands/add_backup.rb +33 -0
  24. data/lib/webbynode/commands/add_key.rb +24 -0
  25. data/lib/webbynode/commands/alias.rb +153 -0
  26. data/lib/webbynode/commands/change_dns.rb +29 -0
  27. data/lib/webbynode/commands/config.rb +15 -0
  28. data/lib/webbynode/commands/delete.rb +25 -0
  29. data/lib/webbynode/commands/help.rb +25 -0
  30. data/lib/webbynode/commands/init.rb +77 -0
  31. data/lib/webbynode/commands/push.rb +70 -0
  32. data/lib/webbynode/commands/remote.rb +28 -0
  33. data/lib/webbynode/commands/restart.rb +25 -0
  34. data/lib/webbynode/commands/start.rb +23 -0
  35. data/lib/webbynode/commands/stop.rb +23 -0
  36. data/lib/webbynode/commands/tasks.rb +149 -0
  37. data/lib/webbynode/commands/version.rb +8 -0
  38. data/lib/webbynode/commands/webbies.rb +30 -0
  39. data/lib/webbynode/git.rb +112 -0
  40. data/lib/webbynode/io.rb +175 -0
  41. data/lib/webbynode/notify.rb +19 -0
  42. data/lib/webbynode/option.rb +84 -0
  43. data/lib/webbynode/parameter.rb +27 -0
  44. data/lib/webbynode/properties.rb +43 -0
  45. data/lib/webbynode/push_and.rb +16 -0
  46. data/lib/webbynode/remote_executor.rb +21 -0
  47. data/lib/webbynode/server.rb +39 -0
  48. data/lib/webbynode/ssh.rb +65 -0
  49. data/lib/webbynode/ssh_keys.rb +36 -0
  50. data/lib/webbynode.rb +56 -0
  51. data/spec/fixtures/aliases +0 -0
  52. data/spec/fixtures/api/credentials +3 -0
  53. data/spec/fixtures/api/dns +30 -0
  54. data/spec/fixtures/api/dns_a_record +20 -0
  55. data/spec/fixtures/api/dns_a_record_already_exists +15 -0
  56. data/spec/fixtures/api/dns_a_record_error +13 -0
  57. data/spec/fixtures/api/dns_new_zone +17 -0
  58. data/spec/fixtures/api/webbies +26 -0
  59. data/spec/fixtures/api/webbies_unauthorized +12 -0
  60. data/spec/fixtures/api/webby +6 -0
  61. data/spec/fixtures/commands/tasks/after_push +3 -0
  62. data/spec/fixtures/fixture_helpers +2 -0
  63. data/spec/fixtures/git/config/210.11.13.12 +9 -0
  64. data/spec/fixtures/git/config/67.23.79.31 +9 -0
  65. data/spec/fixtures/git/config/67.23.79.32 +9 -0
  66. data/spec/fixtures/git/config/config +9 -0
  67. data/spec/fixtures/git/status/clean +2 -0
  68. data/spec/fixtures/git/status/dirty +9 -0
  69. data/spec/fixtures/pushand +2 -0
  70. data/spec/spec_helper.rb +58 -0
  71. data/spec/webbynode/api_client_spec.rb +227 -0
  72. data/spec/webbynode/application_spec.rb +50 -0
  73. data/spec/webbynode/command_spec.rb +285 -0
  74. data/spec/webbynode/commands/add_backup_spec.rb +66 -0
  75. data/spec/webbynode/commands/add_key_spec.rb +58 -0
  76. data/spec/webbynode/commands/alias_spec.rb +213 -0
  77. data/spec/webbynode/commands/change_dns_spec.rb +51 -0
  78. data/spec/webbynode/commands/config_spec.rb +22 -0
  79. data/spec/webbynode/commands/delete_spec.rb +78 -0
  80. data/spec/webbynode/commands/help_spec.rb +43 -0
  81. data/spec/webbynode/commands/init_spec.rb +326 -0
  82. data/spec/webbynode/commands/push_spec.rb +175 -0
  83. data/spec/webbynode/commands/remote_spec.rb +76 -0
  84. data/spec/webbynode/commands/tasks_spec.rb +288 -0
  85. data/spec/webbynode/commands/version_spec.rb +18 -0
  86. data/spec/webbynode/commands/webbies_spec.rb +27 -0
  87. data/spec/webbynode/git_spec.rb +310 -0
  88. data/spec/webbynode/io_spec.rb +198 -0
  89. data/spec/webbynode/option_spec.rb +48 -0
  90. data/spec/webbynode/parameter_spec.rb +70 -0
  91. data/spec/webbynode/push_and_spec.rb +28 -0
  92. data/spec/webbynode/remote_executor_spec.rb +25 -0
  93. data/spec/webbynode/server_spec.rb +101 -0
  94. data/webbynode.gemspec +25 -16
  95. metadata +182 -14
  96. data/lib/wn.rb +0 -106
  97. data/test/test_helper.rb +0 -9
  98. data/test/test_wn.rb +0 -220
@@ -0,0 +1,22 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
+
4
+ describe Webbynode::Commands::Config do
5
+ let(:api) { double("ApiClient") }
6
+
7
+ it "should write ~/.webbynode config file" do
8
+ api.should_receive(:init_credentials).with({})
9
+
10
+ cmd = Webbynode::Commands::Config.new
11
+ cmd.should_receive(:api).any_number_of_times.and_return(api)
12
+ cmd.run
13
+ end
14
+
15
+ it "should write ~/.webbynode config file" do
16
+ api.should_receive(:init_credentials).with({ :email => "email", :token => 'token'} )
17
+
18
+ cmd = Webbynode::Commands::Config.new("--email=email", "--token=token")
19
+ cmd.should_receive(:api).any_number_of_times.and_return(api)
20
+ cmd.run
21
+ end
22
+ end
@@ -0,0 +1,78 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
+
4
+ describe Webbynode::Commands::Delete do
5
+ let(:cmd) { Webbynode::Commands::Delete.new }
6
+ let(:pushand) { double("PushAnd").as_null_object }
7
+ let(:re) { double("RemoteExecutor").as_null_object }
8
+ let(:io) { double("Io").as_null_object }
9
+
10
+ def setup_mocks(cmd)
11
+ cmd.should_receive(:pushand).any_number_of_times.and_return(pushand)
12
+ cmd.should_receive(:remote_executor).any_number_of_times.and_return(re)
13
+ cmd.should_receive(:io).any_number_of_times.and_return(io)
14
+ end
15
+
16
+ before do
17
+ setup_mocks(cmd)
18
+ end
19
+
20
+ it "should run delete_app for the current application" do
21
+ pushand.should_receive(:parse_remote_app_name).and_return("myapp")
22
+ re.should_receive(:exec).with("delete_app myapp --force", true)
23
+ cmd.should_receive(:ask).with("Do you really want to delete application myapp (y/n)? ").and_return("y")
24
+ cmd.run
25
+ end
26
+
27
+ context "when pushand doesn't exist" do
28
+ it "should poop an easter egg" do
29
+ pushand.should_receive(:present?).and_return(false)
30
+ io.should_receive(:log).with("Ahn!? Hello, McFly, anybody home?", true)
31
+ cmd.stub!(:ask).any_number_of_times
32
+ cmd.ask.stub!(:downcase)
33
+ cmd.execute
34
+ end
35
+ end
36
+
37
+ context "when pushand exists" do
38
+ it "should not poop an easter egg" do
39
+ pushand.should_receive(:present?).and_return(true)
40
+ io.should_not_receive(:log).with("Ahn!? Hello, McFly, anybody home?", true)
41
+ cmd.stub!(:ask).any_number_of_times
42
+ cmd.ask.stub!(:downcase)
43
+ cmd.execute
44
+ end
45
+ end
46
+
47
+ it "should delete if user responds Y" do
48
+ pushand.should_receive(:parse_remote_app_name).and_return("myapp")
49
+ re.should_receive(:exec).with("delete_app myapp --force", true)
50
+ cmd.should_receive(:ask).with("Do you really want to delete application myapp (y/n)? ").and_return("Y")
51
+ cmd.run
52
+ end
53
+
54
+ it "should delete if force option is given" do
55
+ cmd = Webbynode::Commands::Delete.new("--force")
56
+ pushand.should_receive(:parse_remote_app_name).and_return("myapp")
57
+ re.should_receive(:exec).with("delete_app myapp --force", true)
58
+ setup_mocks(cmd)
59
+
60
+ cmd.run
61
+ end
62
+
63
+ it "should ask for confirmation" do
64
+ pushand.should_receive(:parse_remote_app_name).and_return("myapp")
65
+ re.should_receive(:exec).never
66
+ cmd.should_receive(:puts).with("Aborted.")
67
+ cmd.should_receive(:ask).with("Do you really want to delete application myapp (y/n)? ").and_return("n")
68
+ cmd.run
69
+ end
70
+
71
+ it "abort if user didn't respond y" do
72
+ pushand.should_receive(:parse_remote_app_name).and_return("myapp")
73
+ re.should_receive(:exec).never
74
+ cmd.should_receive(:puts).with("Aborted.")
75
+ cmd.should_receive(:ask).with("Do you really want to delete application myapp (y/n)? ").and_return("X")
76
+ cmd.run
77
+ end
78
+ end
@@ -0,0 +1,43 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
+
4
+ describe Webbynode::Commands::Help do
5
+ it "should print the usage, the options and the parameters for a command" do
6
+ CommandHelp = Class.new(Webbynode::Command)
7
+ CommandHelp.summary "Provides help"
8
+ CommandHelp.parameter :name, "My name"
9
+ CommandHelp.parameter :age, "My age"
10
+ CommandHelp.option :force, "Should I force?"
11
+
12
+ CommandHelp.should_receive(:usage).and_return("usage")
13
+ CommandHelp.should_receive(:params_help).and_return("params")
14
+ CommandHelp.should_receive(:options_help).and_return("options")
15
+
16
+ cmd = Webbynode::Commands::Help.new("command_help")
17
+ cmd.run
18
+
19
+ stdout =~ /Provides help/
20
+ stdout =~ /usage/
21
+ stdout =~ /params/
22
+ stdout =~ /options/
23
+ end
24
+
25
+ it "should print only the usage, when no commands or params" do
26
+ AnotherCommandHelp = Class.new(Webbynode::Command)
27
+ AnotherCommandHelp.summary "Provides even more help"
28
+
29
+ AnotherCommandHelp.should_receive(:summary_help).twice.and_return("Provides even more help")
30
+ AnotherCommandHelp.should_receive(:usage).and_return("usage")
31
+ AnotherCommandHelp.should_receive(:params_help).never
32
+ AnotherCommandHelp.should_receive(:options_help).never
33
+
34
+ cmd = Webbynode::Commands::Help.new("another_command_help")
35
+ cmd.run
36
+
37
+ stdout =~ /Provides even more help/
38
+ stdout =~ /summary/
39
+ stdout =~ /usage/
40
+ stdout =~ /params/
41
+ stdout =~ /options/
42
+ end
43
+ end
@@ -0,0 +1,326 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
+
4
+ describe Webbynode::Commands::Init do
5
+ let(:git_handler) { double("dummy_git_handler").as_null_object }
6
+ let(:io_handler) { double("dummy_io_handler").as_null_object }
7
+
8
+ def create_init(ip="4.3.2.1", host=nil, extra=[])
9
+ @command = Webbynode::Commands::Init.new(ip, host, *extra)
10
+ @command.should_receive(:git).any_number_of_times.and_return(git_handler)
11
+ @command.should_receive(:io).any_number_of_times.and_return(io_handler)
12
+ end
13
+
14
+ before(:each) do
15
+ FakeWeb.clean_registry
16
+ create_init
17
+ end
18
+
19
+ context "selecting an engine" do
20
+ it "should create the .webbynode/engine file" do
21
+ command = Webbynode::Commands::Init.new("10.0.1.1", "--engine=php")
22
+ command.option(:engine).should == 'php'
23
+ command.should_receive(:io).any_number_of_times.and_return(io_handler)
24
+
25
+ io_handler.should_receive(:add_setting).with("engine", "php")
26
+ command.run
27
+ end
28
+ end
29
+
30
+ context "when creating a DNS entry with --adddns option" do
31
+ let(:io) { io = double("Io").as_null_object }
32
+
33
+ def create_init(ip="4.3.2.1", host=nil, extra=[])
34
+ @command = Webbynode::Commands::Init.new(ip, host, *extra)
35
+ @command.should_receive(:git).any_number_of_times.and_return(git_handler)
36
+ end
37
+
38
+ it "should setup DNS using Webbynode API" do
39
+ create_init("10.0.1.1", "new.rubyista.info", "--adddns")
40
+
41
+ io.should_receive(:remove_setting).with("dns_alias")
42
+
43
+ api = Webbynode::ApiClient.new
44
+ api.should_receive(:create_record).with("new.rubyista.info", "10.0.1.1")
45
+ git_handler.should_receive(:parse_remote_ip).and_return("10.0.1.1")
46
+
47
+ @command.should_receive(:api).any_number_of_times.and_return(api)
48
+ @command.should_receive(:io).any_number_of_times.and_return(io)
49
+ @command.run
50
+ end
51
+
52
+ it "should setup empty and www records for a tld" do
53
+ create_init("10.0.1.1", "rubyista.info", "--adddns")
54
+
55
+ io.should_receive(:add_setting).with("dns_alias", "'www.rubyista.info'")
56
+
57
+ api = Webbynode::ApiClient.new
58
+ api.should_receive(:create_record).with("rubyista.info", "10.0.1.1")
59
+ api.should_receive(:create_record).with("www.rubyista.info", "10.0.1.1")
60
+ git_handler.should_receive(:parse_remote_ip).any_number_of_times.and_return("10.0.1.1")
61
+
62
+ @command.should_receive(:api).any_number_of_times.and_return(api)
63
+ @command.should_receive(:io).any_number_of_times.and_return(io)
64
+ @command.run
65
+ end
66
+
67
+ it "should setup empty and www records for a non-.com tld" do
68
+ create_init("10.0.1.1", "rubyista.com.br", "--adddns")
69
+
70
+ # io = double("Io")
71
+ # io.should_receive(:properties).with(".webbynode/settings").and_return(stub("Properties"))
72
+
73
+ api = Webbynode::ApiClient.new
74
+ api.should_receive(:create_record).with("rubyista.com.br", "10.0.1.1")
75
+ api.should_receive(:create_record).with("www.rubyista.com.br", "10.0.1.1")
76
+ git_handler.should_receive(:parse_remote_ip).any_number_of_times.and_return("10.0.1.1")
77
+
78
+ @command.should_receive(:io).any_number_of_times.and_return(io)
79
+ @command.should_receive(:api).any_number_of_times.and_return(api)
80
+ @command.run
81
+ end
82
+
83
+ it "should indicate the record already exists" do
84
+ create_init("10.0.1.1", "new.rubyista.info", "--adddns")
85
+
86
+ api = Webbynode::ApiClient.new
87
+ api.should_receive(:create_record).with("new.rubyista.info", "10.0.1.1").and_raise(Webbynode::ApiClient::ApiError.new("Data has already been taken"))
88
+ git_handler.should_receive(:parse_remote_ip).and_return("10.0.1.1")
89
+
90
+ # the DNS setting should remove any dns_aliases on .webbynode/settings
91
+ io = Webbynode::Io.new
92
+ io.should_receive(:remove_setting).with("dns_alias")
93
+
94
+ @command.should_receive(:api).any_number_of_times.and_return(api)
95
+ @command.should_receive(:io).any_number_of_times.and_return(io)
96
+ @command.run
97
+
98
+ stdout.should =~ /The DNS entry for 'new.rubyista.info' already existed, ignoring./
99
+ end
100
+
101
+ it "should show an user friendly error" do
102
+ create_init("10.0.1.1", "new.rubyista.info", "--adddns")
103
+
104
+ api = Webbynode::ApiClient.new
105
+ git_handler.should_receive(:parse_remote_ip).and_return("10.0.1.1")
106
+ api.should_receive(:create_record).with("new.rubyista.info", "10.0.1.1").and_raise(Webbynode::ApiClient::ApiError.new("No DNS entry for id 99999"))
107
+
108
+ # the DNS setting should remove any dns_aliases on .webbynode/settings
109
+ io = Webbynode::Io.new
110
+ io.should_receive(:remove_setting).with("dns_alias")
111
+
112
+ @command.should_receive(:api).any_number_of_times.and_return(api)
113
+ @command.should_receive(:io).any_number_of_times.and_return(io)
114
+ @command.run
115
+
116
+ stdout.should =~ /Couldn't create your DNS entry: No DNS entry for id 99999/
117
+ end
118
+ end
119
+
120
+ it "should ask for user's login email if no credentials" do
121
+ FakeWeb.register_uri(:post, "#{Webbynode::ApiClient.base_uri}/webbies",
122
+ :email => "fcoury@me.com", :response => read_fixture("api/webbies"))
123
+
124
+ io_handler.should_receive(:file_exists?).with(Webbynode::ApiClient::CREDENTIALS_FILE).and_return(false)
125
+ io_handler.should_receive(:app_name).any_number_of_times.and_return("my_app")
126
+
127
+ props = {}
128
+ props.stub(:save)
129
+
130
+ create_init("my_webby_name")
131
+ @command.api.should_receive(:io).any_number_of_times.and_return(io_handler)
132
+ @command.api.should_receive(:ask).with("API token: ").and_return("234def")
133
+ @command.api.should_receive(:ask).with("Login email: ").and_return("abc123")
134
+ @command.api.should_receive(:properties).any_number_of_times.and_return(props)
135
+ @command.run
136
+
137
+ stdout.should =~ /Couldn't find Webby 'my_webby_name' on your account. Your Webbies are/
138
+ stdout.should =~ /'webby3067'/
139
+ stdout.should =~ /' and '/
140
+ stdout.should =~ /'sandbox'/
141
+ end
142
+
143
+ it "should report the error if user provides wrong credentials" do
144
+ FakeWeb.register_uri(:post, "#{Webbynode::ApiClient.base_uri}/webbies",
145
+ :email => "fcoury@me.com", :response => read_fixture("api/webbies_unauthorized"))
146
+
147
+ io_handler.should_receive(:app_name).any_number_of_times.and_return("my_app")
148
+ io_handler.should_receive(:create_file).never
149
+
150
+ create_init("my_webby_name")
151
+
152
+ @command.api.should_receive(:ip_for).and_raise(Webbynode::ApiClient::Unauthorized)
153
+ @command.run
154
+
155
+ stdout.should =~ /Your credentials didn't match any Webbynode account./
156
+ end
157
+
158
+ it "should report Webby doesn't exist" do
159
+ api = double("ApiClient")
160
+ api.should_receive(:ip_for).with("my_webby_name").and_return(nil)
161
+ api.should_receive(:webbies).and_return({
162
+ "one_webby"=>{:name => 'one_webby', :other => 'other'},
163
+ "another_webby"=>{:name => 'another_webby', :other => 'other'}
164
+ })
165
+
166
+ io_handler.should_receive(:app_name).any_number_of_times.and_return("my_app")
167
+
168
+ create_init("my_webby_name")
169
+ @command.should_receive(:api).any_number_of_times.and_return(api)
170
+ @command.run
171
+
172
+ stdout.should =~ /Couldn't find Webby 'my_webby_name' on your account. Your Webbies are/
173
+ stdout.should =~ /'one_webby'/
174
+ stdout.should =~ /' and '/
175
+ stdout.should =~ /'another_webby'/
176
+ end
177
+
178
+ it "should report user doesn't have Webbies" do
179
+ api = double("ApiClient")
180
+ api.should_receive(:ip_for).with("my_webby_name").and_return(nil)
181
+ api.should_receive(:webbies).and_return({})
182
+
183
+ io_handler.should_receive(:app_name).any_number_of_times.and_return("my_app")
184
+
185
+ create_init("my_webby_name")
186
+ @command.should_receive(:api).any_number_of_times.and_return(api)
187
+ @command.run
188
+
189
+ stdout.should =~ /You don't have any active Webbies on your account./
190
+ end
191
+
192
+ it "should try to get Webby's IP if no IP given" do
193
+ api = double("ApiClient")
194
+ api.should_receive(:ip_for).with("my_webby_name").and_return("1.2.3.4")
195
+
196
+ io_handler.should_receive(:app_name).any_number_of_times.and_return("my_app")
197
+ git_handler.should_receive(:present?).and_return(false)
198
+ git_handler.should_receive(:add_remote).with("webbynode", "1.2.3.4", "my_app")
199
+
200
+ create_init("my_webby_name")
201
+ @command.should_receive(:api).and_return(api)
202
+ @command.run
203
+ end
204
+
205
+ context "determining host" do
206
+ it "should assume host is app's name when not given" do
207
+ io_handler.should_receive(:file_exists?).with(".pushand").and_return(false)
208
+ io_handler.should_receive(:app_name).any_number_of_times.and_return("application_name")
209
+ io_handler.should_receive(:create_file).with(".pushand", "#! /bin/bash\nphd $0 application_name application_name\n", true)
210
+
211
+ @command.run
212
+ end
213
+
214
+ it "should assume host is app's name when not given" do
215
+ create_init("1.2.3.4", "my.com.br")
216
+
217
+ io_handler.should_receive(:file_exists?).with(".pushand").and_return(false)
218
+ io_handler.should_receive(:app_name).any_number_of_times.and_return("application_name")
219
+ io_handler.should_receive(:create_file).with(".pushand", "#! /bin/bash\nphd $0 application_name my.com.br\n", true)
220
+
221
+ @command.run
222
+ end
223
+ end
224
+
225
+ context "when .gitignore is not present" do
226
+ it "should create the standard .gitignore" do
227
+ io_handler.should_receive(:file_exists?).with(".gitignore").and_return(false)
228
+ git_handler.should_receive(:add_git_ignore)
229
+
230
+ @command.run
231
+ end
232
+ end
233
+
234
+ context "when .webbynode is not present" do
235
+ it "should create the .webbynode system folder and stub files" do
236
+ io_handler.should_receive(:directory?).with(".webbynode").and_return(false)
237
+ io_handler.should_receive(:exec).with("mkdir -p .webbynode/tasks")
238
+ io_handler.should_receive(:create_file).with(".webbynode/tasks/after_push", "")
239
+ io_handler.should_receive(:create_file).with(".webbynode/tasks/before_push", "")
240
+ io_handler.should_receive(:create_file).with(".webbynode/aliases", "")
241
+
242
+ @command.run
243
+ end
244
+ end
245
+
246
+ context "when .pushand is not present" do
247
+ it "should be created and made an executable" do
248
+ io_handler.should_receive(:file_exists?).with(".pushand").and_return(false)
249
+ io_handler.should_receive(:app_name).any_number_of_times.and_return("mah_app")
250
+ io_handler.should_receive(:create_file).with(".pushand", "#! /bin/bash\nphd $0 mah_app mah_app\n", true)
251
+
252
+ @command.run
253
+ end
254
+ end
255
+
256
+ context "when .pushand is present" do
257
+ it "should not be created" do
258
+ io_handler.should_receive(:file_exists?).with(".pushand").and_return(true)
259
+ io_handler.should_receive(:create_file).never
260
+
261
+ @command.run
262
+ end
263
+ end
264
+
265
+ context "when git repo doesn't exist yet" do
266
+ it "should create a new git repo" do
267
+ git_handler.should_receive(:present?).and_return(false)
268
+ git_handler.should_receive(:init)
269
+
270
+ @command.run
271
+ end
272
+
273
+ it "should add a new remote" do
274
+ io_handler.should_receive(:app_name).any_number_of_times.and_return("my_app")
275
+ git_handler.should_receive(:present?).and_return(false)
276
+ git_handler.should_receive(:add_remote).with("webbynode", "4.3.2.1", "my_app")
277
+
278
+ @command.run
279
+ end
280
+
281
+ it "should add everything" do
282
+ git_handler.should_receive(:present?).and_return(false)
283
+ git_handler.should_receive(:add).with(".")
284
+
285
+ @command.run
286
+ end
287
+
288
+ it "should create the initial commit" do
289
+ git_handler.should_receive(:present?).and_return(false)
290
+ git_handler.should_receive(:commit).with("Initial commit")
291
+
292
+ @command.run
293
+ end
294
+
295
+ it "should log a message to the user when it's finished" do
296
+ io_handler.should_receive(:app_name).any_number_of_times.and_return("my_app")
297
+ io_handler.should_receive(:log).with("Application my_app ready for Rapid Deployment", :finish)
298
+
299
+ @command.run
300
+ end
301
+ end
302
+
303
+ context "when git repo is initialized" do
304
+ it "should not create a commit" do
305
+ git_handler.should_receive(:present?).and_return(true)
306
+ git_handler.should_receive(:commit).never
307
+
308
+ @command.run
309
+ end
310
+
311
+ it "should try to add a remote" do
312
+ git_handler.should_receive(:present?).and_return(true)
313
+ git_handler.should_receive(:add_remote)
314
+
315
+ @command.run
316
+ end
317
+
318
+ it "should tell the user it's already initialized" do
319
+ git_handler.should_receive(:present?).and_return(true)
320
+ git_handler.should_receive(:add_remote).and_raise(Webbynode::GitRemoteAlreadyExistsError)
321
+
322
+ io_handler.should_receive(:log).with("Application already initialized.", true)
323
+ @command.run
324
+ end
325
+ end
326
+ end
@@ -0,0 +1,175 @@
1
+ # Load Spec Helper
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'spec_helper')
3
+
4
+ describe Webbynode::Commands::Push do
5
+
6
+ let(:push) { Webbynode::Commands::Push.new }
7
+ let(:io) { double('Io').as_null_object }
8
+ let(:re) { double('RemoteExecutor').as_null_object }
9
+ let(:pushand) { double('PushAnd').as_null_object }
10
+ let(:git) { double('Git').as_null_object }
11
+
12
+ before(:each) do
13
+ push.should_receive(:io).any_number_of_times.and_return(io)
14
+ push.should_receive(:remote_executor).any_number_of_times.and_return(re)
15
+ push.should_receive(:pushand).any_number_of_times.and_return(pushand)
16
+ push.should_receive(:git).any_number_of_times.and_return(git)
17
+ push.before_tasks.stub!(:read_tasks)
18
+ push.after_tasks.stub!(:read_tasks)
19
+ end
20
+
21
+ context "when the user runs the command" do
22
+ it "should display a message that the application is being pushed to the webby" do
23
+ pushand.should_receive(:parse_remote_app_name).and_return("test.webbynode.com")
24
+ io.should_receive(:log).with("Pushing test.webbynode.com", :start)
25
+ push.stub!(:exec)
26
+ push.execute
27
+ end
28
+
29
+ it "should push the application to the webby" do
30
+ io.should_receive(:exec).with("git push webbynode master", false)
31
+ push.execute
32
+ end
33
+
34
+ it "should not push and warn the user if git status is not clean" do
35
+ git.should_receive(:clean?).and_return(false)
36
+ lambda { push.execute }.should raise_error(Webbynode::Command::CommandError,
37
+ "Cannot push because you have pending changes. Do a git commit or add changes to .gitignore.")
38
+ end
39
+
40
+ it "should not push and warn the user if git status is not clean and the user uses --dirty" do
41
+ pushcmd = Webbynode::Commands::Push.new("--dirty")
42
+ pushcmd.should_receive(:io).any_number_of_times.and_return(io)
43
+ pushcmd.should_receive(:remote_executor).any_number_of_times.and_return(re)
44
+ pushcmd.should_receive(:pushand).any_number_of_times.and_return(pushand)
45
+ pushcmd.should_receive(:git).any_number_of_times.and_return(git)
46
+ pushcmd.before_tasks.stub!(:read_tasks)
47
+ pushcmd.after_tasks.stub!(:read_tasks)
48
+
49
+ pushand.should_receive(:parse_remote_app_name).and_return("app")
50
+ io.should_receive(:log).with("Finished pushing app", :finish)
51
+ git.should_receive(:clean?).never
52
+
53
+ pushcmd.execute
54
+ end
55
+
56
+ context "when succesful" do
57
+ it "should notify the user" do
58
+ pushand.should_receive(:parse_remote_app_name).and_return("test.webbynode.com")
59
+ io.should_receive(:log).with("Finished pushing test.webbynode.com", :finish)
60
+ push.execute
61
+ end
62
+ end
63
+
64
+ describe "Tasks" do
65
+ it "should have 2 before_tasks present" do
66
+ push.execute
67
+ 2.times { push.before_tasks.session_tasks << "foo" }
68
+ push.before_tasks.session_tasks.should have(2).session_tasks
69
+ push.before_tasks.should be_an_instance_of(Webbynode::Commands::Tasks)
70
+ end
71
+
72
+ it "should have 2 after_tasks present" do
73
+ push.execute
74
+ 2.times { push.after_tasks.session_tasks << "foo" }
75
+ push.after_tasks.session_tasks.should have(2).session_tasks
76
+ push.after_tasks.should be_an_instance_of(Webbynode::Commands::Tasks)
77
+ end
78
+
79
+ it "should read the tasks files to see whether there are tasks available" do
80
+ push.before_tasks.should_receive(:read_tasks).with(Webbynode::Commands::Tasks::BeforePushTasksFile)
81
+ push.after_tasks.should_receive(:read_tasks).with(Webbynode::Commands::Tasks::AfterPushTasksFile)
82
+ push.execute
83
+ end
84
+
85
+ it "should check if there are any before_tasks or after_tasks" do
86
+ push.before_tasks.should_receive(:has_tasks?)
87
+ push.after_tasks.should_receive(:has_tasks?)
88
+ push.execute
89
+ end
90
+
91
+ it "should ensure that there are at least blank files available to read from" do
92
+ push.before_tasks.should_receive(:ensure_tasks_folder)
93
+ push.execute
94
+ end
95
+
96
+ it "should not initialize the before_tasks if there aren't any tasks to perform" do
97
+ push.before_tasks.should_receive(:has_tasks?).and_return(false)
98
+ push.should_not_receive(:perform_before_tasks)
99
+ push.execute
100
+ end
101
+
102
+ it "should not initialize the after_tasks if there aren't any tasks to perform" do
103
+ push.after_tasks.should_receive(:has_tasks?).and_return(false)
104
+ push.should_not_receive(:perform_after_tasks)
105
+ push.execute
106
+ end
107
+ end
108
+
109
+ describe "before_push tasks" do
110
+ context "when there are one or more tasks available" do
111
+ before(:each) do
112
+ push.before_tasks.stub!(:has_tasks?).and_return(true)
113
+ end
114
+
115
+ it "should perform these tasks in order" do
116
+ push.should_receive(:perform_before_tasks)
117
+ push.execute
118
+ end
119
+ end
120
+ end
121
+
122
+ describe "after_push tasks" do
123
+ context "when there are one or more tasks available" do
124
+ before(:each) do
125
+ push.after_tasks.stub!(:has_tasks?).and_return(true)
126
+ end
127
+
128
+ it "should perform these tasks in order" do
129
+ push.should_receive(:perform_after_tasks)
130
+ push.execute
131
+ end
132
+ end
133
+ end
134
+
135
+ describe "#perform_before_tasks" do
136
+ before(:each) do
137
+ push.before_tasks.stub!(:has_tasks?).and_return(true)
138
+ io.stub!(:exec).with("git push webbynode master")
139
+ end
140
+
141
+ it "should provide feedback to the user that it's going to perform the tasks" do
142
+ io.should_receive(:log).with("Performing Before Push Tasks...", :action)
143
+ push.execute
144
+ end
145
+
146
+ it "should loop through each of the tasks, perform them and provide feedback" do
147
+ 3.times { |n| push.before_tasks.session_tasks << "Task #{n}" }
148
+ 3.times { |n| io.should_receive(:exec).exactly(:once).with("Task #{n}") }
149
+ 3.times { |n| io.should_receive(:log).exactly(:once).with(" Performing Task: Task #{n}", :action)}
150
+ push.execute
151
+ end
152
+ end
153
+
154
+ describe "#perform_after_tasks" do
155
+ before(:each) do
156
+ push.after_tasks.stub!(:has_tasks?).and_return(true)
157
+ io.stub!(:exec).with("git push webbynode master")
158
+ end
159
+
160
+ it "should provide feedback to the user that it's going to perform the tasks" do
161
+ io.should_receive(:log).with("Performing After Push Tasks...", :action)
162
+ push.execute
163
+ end
164
+
165
+ it "should loop through each of the tasks, perform them and provide feedback" do
166
+ 3.times { |n| push.after_tasks.session_tasks << "Task #{n}" }
167
+ 3.times { |n| re.should_receive(:exec).exactly(:once).with("cd test.webbynode.com; Task #{n}", true) }
168
+ 3.times { |n| io.should_receive(:log).exactly(:once).with(" Performing Task: Task #{n}", :action) }
169
+ pushand.should_receive(:parse_remote_app_name).exactly(4).times.and_return("test.webbynode.com")
170
+ push.execute
171
+ end
172
+ end
173
+
174
+ end
175
+ end