cf 1.1.3.rc1 → 1.1.4
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/lib/cf/cli.rb +2 -7
- data/lib/cf/cli/organization/delete.rb +4 -6
- data/lib/cf/cli/service/create.rb +23 -17
- data/lib/cf/cli/space/create.rb +43 -41
- data/lib/cf/cli/space/space.rb +49 -46
- data/lib/cf/version.rb +1 -1
- data/lib/console/console.rb +1 -1
- data/spec/cf/cli/app/delete_spec.rb +16 -28
- data/spec/cf/cli/app/instances_spec.rb +4 -5
- data/spec/cf/cli/app/push/create_spec.rb +362 -373
- data/spec/cf/cli/app/push_spec.rb +216 -215
- data/spec/cf/cli/app/rename_spec.rb +28 -31
- data/spec/cf/cli/app/scale_spec.rb +44 -41
- data/spec/cf/cli/app/start_spec.rb +194 -193
- data/spec/cf/cli/app/stats_spec.rb +55 -56
- data/spec/cf/cli/domain/map_spec.rb +105 -102
- data/spec/cf/cli/domain/unmap_spec.rb +60 -56
- data/spec/cf/cli/organization/delete_spec.rb +85 -84
- data/spec/cf/cli/organization/orgs_spec.rb +80 -83
- data/spec/cf/cli/organization/rename_spec.rb +90 -89
- data/spec/cf/cli/populators/organization_spec.rb +117 -119
- data/spec/cf/cli/populators/space_spec.rb +107 -108
- data/spec/cf/cli/populators/target_spec.rb +17 -12
- data/spec/cf/cli/route/delete_spec.rb +4 -4
- data/spec/cf/cli/route/map_spec.rb +106 -102
- data/spec/cf/cli/route/unmap_spec.rb +5 -5
- data/spec/cf/cli/service/create_spec.rb +74 -46
- data/spec/cf/cli/service/rename_spec.rb +29 -33
- data/spec/cf/cli/service/services_spec.rb +48 -48
- data/spec/cf/cli/space/base_spec.rb +39 -32
- data/spec/cf/cli/space/create_spec.rb +52 -53
- data/spec/cf/cli/space/delete_spec.rb +84 -85
- data/spec/cf/cli/space/rename_spec.rb +93 -94
- data/spec/cf/cli/space/space_spec.rb +60 -60
- data/spec/cf/cli/space/spaces_spec.rb +75 -80
- data/spec/cf/cli/space/switch_space_spec.rb +45 -48
- data/spec/cf/cli/start/info_spec.rb +4 -6
- data/spec/cf/cli/start/login_spec.rb +18 -20
- data/spec/cf/cli/start/logout_spec.rb +36 -37
- data/spec/cf/cli/start/target_spec.rb +86 -89
- data/spec/cf/cli/user/create_spec.rb +83 -84
- data/spec/cf/cli/user/passwd_spec.rb +87 -86
- data/spec/cf/cli/user/register_spec.rb +109 -108
- data/spec/cf/cli_spec.rb +305 -310
- data/spec/console/console_spec.rb +58 -58
- data/spec/factories/cfoundry/v2/domain_factory.rb +8 -0
- data/spec/factories/cfoundry/v2/route_factory.rb +8 -0
- data/spec/factories/cfoundry/v2/user_factory.rb +7 -0
- data/spec/features/org_spec.rb +11 -11
- data/spec/manifests/manifests_spec.rb +21 -21
- data/spec/manifests/plugin_spec.rb +34 -34
- data/spec/spec_helper.rb +1 -2
- data/spec/support/cli_helper.rb +5 -14
- data/spec/support/factory_girl.rb +6 -0
- data/spec/support/interact_helper.rb +5 -15
- data/spec/support/shared_examples/errors.rb +1 -1
- data/spec/tunnel/plugin_spec.rb +2 -2
- data/spec/tunnel/tunnel_spec.rb +5 -5
- metadata +36 -28
@@ -1,143 +1,144 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module CF
|
4
|
+
module User
|
5
|
+
describe Register do
|
6
|
+
let(:client) { fake_client }
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
before do
|
9
|
+
stub_client_and_precondition
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
describe "metadata" do
|
13
|
+
let(:command) { Mothership.commands[:register] }
|
14
|
+
|
15
|
+
describe "command" do
|
16
|
+
subject { command }
|
17
|
+
its(:description) { should eq "Create a user and log in" }
|
18
|
+
it { expect(Mothership::Help.group(:admin, :user)).to include(subject) }
|
19
|
+
end
|
16
20
|
|
17
|
-
|
21
|
+
include_examples "inputs must have descriptions"
|
18
22
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
describe "arguments" do
|
24
|
+
subject { command.arguments }
|
25
|
+
it "have the correct commands" do
|
26
|
+
should eq [
|
27
|
+
{:type => :optional, :value => nil, :name => :email}
|
28
|
+
]
|
29
|
+
end
|
30
|
+
end
|
25
31
|
end
|
26
|
-
end
|
27
|
-
end
|
28
32
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
33
|
+
describe "#register" do
|
34
|
+
let(:email) { "a@b.com" }
|
35
|
+
let(:password) { "password" }
|
36
|
+
let(:verify_password) { password }
|
37
|
+
let(:force) { false }
|
38
|
+
let(:login) { false }
|
39
|
+
let(:score) { :strong }
|
40
|
+
|
41
|
+
before do
|
42
|
+
client.stub(:register)
|
43
|
+
client.base.stub(:password_score) { score }
|
44
|
+
end
|
42
45
|
|
43
|
-
|
46
|
+
subject { cf %W[register --email #{email} --password #{password} --verify #{verify_password} --#{bool_flag(:login)} --#{bool_flag(:force)}] }
|
44
47
|
|
45
|
-
|
46
|
-
|
48
|
+
context "when the passwords dont match" do
|
49
|
+
let(:verify_password) { "other_password" }
|
47
50
|
|
48
|
-
|
51
|
+
it { should eq 1 }
|
49
52
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
53
|
+
it "fails" do
|
54
|
+
subject
|
55
|
+
expect(error_output).to say("Passwords do not match.")
|
56
|
+
end
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
it "doesn't print out the score" do
|
59
|
+
subject
|
60
|
+
expect(output).to_not say("strength")
|
61
|
+
end
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
it "doesn't log in or register" do
|
64
|
+
client.should_not_receive(:register)
|
65
|
+
dont_allow_invoke
|
66
|
+
subject
|
67
|
+
end
|
65
68
|
|
66
|
-
|
67
|
-
|
69
|
+
context "and the force flag is passed" do
|
70
|
+
let(:force) { true }
|
68
71
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
72
|
+
it "doesn't verify the password" do
|
73
|
+
client.should_receive(:register).with(email, password)
|
74
|
+
subject
|
75
|
+
expect(error_output).to_not say("Passwords do not match.")
|
76
|
+
end
|
77
|
+
end
|
73
78
|
end
|
74
|
-
end
|
75
|
-
end
|
76
79
|
|
77
|
-
|
78
|
-
|
80
|
+
context "when the password is good or strong" do
|
81
|
+
it { should eq 0 }
|
79
82
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
83
|
+
it "prints out the password score" do
|
84
|
+
subject
|
85
|
+
expect(stdout.string).to include "Your password strength is: strong"
|
86
|
+
end
|
84
87
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
88
|
+
it "registers the user" do
|
89
|
+
client.should_receive(:register).with(email, password)
|
90
|
+
subject
|
91
|
+
end
|
89
92
|
|
90
|
-
|
91
|
-
|
93
|
+
context "and the login flag is true" do
|
94
|
+
let(:login) { true }
|
92
95
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
+
it "logs in" do
|
97
|
+
described_class.any_instance.should_receive(:invoke).with(:login, :username => email, :password => password)
|
98
|
+
subject
|
99
|
+
end
|
96
100
|
end
|
97
|
-
subject
|
98
|
-
end
|
99
|
-
end
|
100
101
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
102
|
+
context "and the login flag is false" do
|
103
|
+
it "doesn't log in" do
|
104
|
+
described_class.any_instance.should_not_receive(:invoke)
|
105
|
+
subject
|
106
|
+
end
|
105
107
|
end
|
106
|
-
subject
|
107
108
|
end
|
108
|
-
end
|
109
|
-
end
|
110
109
|
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
context "when the password is weak" do
|
111
|
+
let(:score) { :weak }
|
112
|
+
let(:login) { true }
|
114
113
|
|
115
|
-
|
114
|
+
it { should eq 1 }
|
116
115
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
116
|
+
it "prints out the password score" do
|
117
|
+
subject
|
118
|
+
expect(error_output).to say("Your password strength is: weak")
|
119
|
+
end
|
121
120
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
121
|
+
it "doesn't register" do
|
122
|
+
client.should_not_receive(:register).with(email, password)
|
123
|
+
subject
|
124
|
+
end
|
126
125
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
126
|
+
it "doesn't log in" do
|
127
|
+
dont_allow_invoke :login
|
128
|
+
subject
|
129
|
+
end
|
130
|
+
end
|
132
131
|
|
133
|
-
|
134
|
-
|
132
|
+
context "when arguments are not passed in the command line" do
|
133
|
+
subject { cf %W[register --no-force --no-login] }
|
135
134
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
135
|
+
it "asks for the email, password and confirm password" do
|
136
|
+
mock_ask("Email") { email }
|
137
|
+
mock_ask("Password", anything) { password }
|
138
|
+
mock_ask("Confirm Password", anything) { verify_password }
|
139
|
+
subject
|
140
|
+
end
|
141
|
+
end
|
141
142
|
end
|
142
143
|
end
|
143
144
|
end
|
data/spec/cf/cli_spec.rb
CHANGED
@@ -1,446 +1,441 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
module CF
|
4
|
+
describe CLI do
|
5
|
+
let(:context) { CF::CLI.new }
|
6
|
+
let(:command) { nil }
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
let(:fake_home_dir) { nil }
|
9
|
+
stub_home_dir_with { fake_home_dir }
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
describe "#wrap_errors" do
|
12
|
+
let(:inputs) { {} }
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
subject do
|
15
|
+
capture_output do
|
16
|
+
context.stub(:input) { inputs }
|
17
|
+
context.wrap_errors { action.call }
|
18
|
+
end
|
17
19
|
end
|
18
|
-
end
|
19
20
|
|
20
|
-
|
21
|
-
|
21
|
+
context "with a CFoundry::Timeout" do
|
22
|
+
let(:action) { proc { raise CFoundry::Timeout.new(123, "fizzbuzz") } }
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
24
|
+
it_behaves_like "an error that's obvious to the user", :with_message => "fizzbuzz"
|
25
|
+
end
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
context "with a UserError" do
|
28
|
+
let(:action) { proc { context.fail "foo bar" } }
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
it_behaves_like "an error that's obvious to the user",
|
31
|
+
:with_message => "foo bar"
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
it "saves it in the crashlog" do
|
34
|
+
context.should_receive(:log_error)
|
35
|
+
subject
|
36
|
+
end
|
36
37
|
end
|
37
|
-
end
|
38
|
-
|
39
|
-
context "with a UserFriendlyError" do
|
40
|
-
let(:action) { proc { raise CF::UserFriendlyError.new("user friendly") } }
|
41
|
-
|
42
|
-
it_behaves_like "an error that's obvious to the user",
|
43
|
-
:with_message => "user friendly"
|
44
|
-
end
|
45
38
|
|
46
|
-
|
47
|
-
|
39
|
+
context "with a UserFriendlyError" do
|
40
|
+
let(:action) { proc { raise CF::UserFriendlyError.new("user friendly") } }
|
48
41
|
|
49
|
-
|
50
|
-
|
51
|
-
|
42
|
+
it_behaves_like "an error that's obvious to the user",
|
43
|
+
:with_message => "user friendly"
|
44
|
+
end
|
52
45
|
|
53
|
-
|
54
|
-
|
46
|
+
context "with a SystemExit" do
|
47
|
+
let(:action) { proc { exit 1 } }
|
55
48
|
|
56
|
-
|
57
|
-
|
58
|
-
|
49
|
+
it_behaves_like "an error that gets passed through",
|
50
|
+
:with_exception => SystemExit
|
51
|
+
end
|
59
52
|
|
60
|
-
|
61
|
-
|
53
|
+
context "with a Mothership::Error" do
|
54
|
+
let(:action) { proc { raise Mothership::Error } }
|
62
55
|
|
63
|
-
|
64
|
-
|
65
|
-
subject
|
56
|
+
it_behaves_like "an error that gets passed through",
|
57
|
+
:with_exception => Mothership::Error
|
66
58
|
end
|
67
|
-
end
|
68
59
|
|
69
|
-
|
70
|
-
|
71
|
-
let(:asked) { false }
|
60
|
+
context "with an Interrupt" do
|
61
|
+
let(:action) { proc { raise Interrupt } }
|
72
62
|
|
73
|
-
|
74
|
-
|
63
|
+
it "sets the exit code to 130" do
|
64
|
+
context.should_receive(:exit_status).with(130)
|
65
|
+
subject
|
66
|
+
end
|
75
67
|
end
|
76
68
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
69
|
+
context "when CC can't decode the auth token" do
|
70
|
+
let(:action) { proc { raise CFoundry::InvalidAuthToken.new("foo bar") } }
|
71
|
+
let(:asked) { false }
|
81
72
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
73
|
+
before do
|
74
|
+
$cf_asked_auth = asked
|
75
|
+
end
|
87
76
|
|
88
|
-
|
89
|
-
|
90
|
-
|
77
|
+
it "tells the user they are not authenticated" do
|
78
|
+
subject
|
79
|
+
expect(stdout.string).to include "Invalid authentication token. Try logging in again with 'cf login'. If problems continue, please contact your Cloud Operator."
|
80
|
+
end
|
91
81
|
|
92
|
-
|
93
|
-
|
82
|
+
it "exits without attempting to login again" do
|
83
|
+
context.should_not_receive(:invoke)
|
84
|
+
subject
|
85
|
+
end
|
94
86
|
end
|
95
87
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
expect(stdout.string).to include "Not authenticated! Try logging in:"
|
100
|
-
expect($cf_asked_auth).to be_true
|
101
|
-
end
|
88
|
+
context "with a CFoundry authentication error" do
|
89
|
+
let(:action) { proc { raise CFoundry::Forbidden.new("foo bar") } }
|
90
|
+
let(:asked) { false }
|
102
91
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
92
|
+
before do
|
93
|
+
$cf_asked_auth = asked
|
94
|
+
end
|
107
95
|
|
108
|
-
|
109
|
-
|
96
|
+
it "tells the user they are not authenticated" do
|
97
|
+
context.stub(:invoke)
|
98
|
+
subject
|
99
|
+
expect(stdout.string).to include "Not authenticated! Try logging in:"
|
100
|
+
expect($cf_asked_auth).to be_true
|
101
|
+
end
|
110
102
|
|
111
|
-
it "
|
112
|
-
|
103
|
+
it "asks the user to log in" do
|
104
|
+
context.should_receive(:invoke).with(:login)
|
113
105
|
subject
|
114
106
|
end
|
115
107
|
|
116
|
-
|
117
|
-
:
|
118
|
-
end
|
119
|
-
end
|
108
|
+
context "and after logging in they got another authentication error" do
|
109
|
+
let(:asked) { true }
|
120
110
|
|
121
|
-
|
122
|
-
|
111
|
+
it "does not ask them to log in" do
|
112
|
+
context.should_not_receive(:invoke)
|
113
|
+
subject
|
114
|
+
end
|
123
115
|
|
124
|
-
|
125
|
-
|
126
|
-
|
116
|
+
it_behaves_like "an error that's obvious to the user",
|
117
|
+
:with_message => "Denied: foo bar"
|
118
|
+
end
|
127
119
|
end
|
128
120
|
|
129
|
-
|
130
|
-
|
131
|
-
expect(stderr.string).to include "RuntimeError: foo bar"
|
132
|
-
end
|
121
|
+
context "with an arbitrary exception" do
|
122
|
+
let(:action) { proc { raise "foo bar" } }
|
133
123
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
124
|
+
it "logs the error" do
|
125
|
+
context.should_receive(:log_error).with(anything)
|
126
|
+
subject
|
127
|
+
end
|
138
128
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
129
|
+
it "prints the message" do
|
130
|
+
subject
|
131
|
+
expect(stderr.string).to include "RuntimeError: foo bar"
|
132
|
+
end
|
143
133
|
|
144
|
-
|
145
|
-
|
134
|
+
it "sets the exit code to 1" do
|
135
|
+
context.should_receive(:exit_status).with(1)
|
136
|
+
subject
|
137
|
+
end
|
146
138
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
end
|
139
|
+
it "tells the user to check ~/.cf/crash" do
|
140
|
+
subject
|
141
|
+
expect(stderr.string).to include CF::CRASH_FILE
|
142
|
+
end
|
152
143
|
|
153
|
-
|
154
|
-
|
155
|
-
let(:client) { fake_client }
|
144
|
+
context "when we are debugging" do
|
145
|
+
let(:inputs) { {:debug => true} }
|
156
146
|
|
157
|
-
|
158
|
-
|
159
|
-
|
147
|
+
it_behaves_like "an error that gets passed through",
|
148
|
+
:with_exception => RuntimeError
|
149
|
+
end
|
160
150
|
end
|
161
151
|
end
|
162
152
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
context.execute(command, [])
|
167
|
-
end
|
168
|
-
end
|
153
|
+
describe "#execute" do
|
154
|
+
let(:inputs) { {} }
|
155
|
+
let(:client) { fake_client }
|
169
156
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
let(:auth_token) { CFoundry::AuthToken.new("old-header") }
|
174
|
-
let(:new_auth_token) { CFoundry::AuthToken.new("new-header") }
|
157
|
+
before do
|
158
|
+
stub_client
|
159
|
+
end
|
175
160
|
|
176
|
-
|
177
|
-
|
178
|
-
|
161
|
+
subject do
|
162
|
+
capture_output do
|
163
|
+
context.stub(:input) { inputs }
|
164
|
+
context.execute(command, [])
|
179
165
|
end
|
166
|
+
end
|
180
167
|
|
181
|
-
|
182
|
-
|
168
|
+
describe "token refreshing" do
|
169
|
+
let(:context) { TokenRefreshDummy.new }
|
170
|
+
let(:command) { Mothership.commands[:refresh_token] }
|
171
|
+
let(:auth_token) { CFoundry::AuthToken.new("old-header") }
|
172
|
+
let(:new_auth_token) { CFoundry::AuthToken.new("new-header") }
|
183
173
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
client.token = self.class.new_token
|
174
|
+
class TokenRefreshDummy < CF::CLI
|
175
|
+
class << self
|
176
|
+
attr_accessor :new_token
|
188
177
|
end
|
189
|
-
end
|
190
|
-
end
|
191
178
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
179
|
+
def precondition;
|
180
|
+
end
|
181
|
+
|
182
|
+
desc "XXX"
|
183
|
+
|
184
|
+
def refresh_token
|
185
|
+
if client
|
186
|
+
client.token = self.class.new_token
|
187
|
+
end
|
188
|
+
end
|
196
189
|
end
|
197
190
|
|
198
|
-
context "when
|
199
|
-
|
200
|
-
|
201
|
-
|
191
|
+
context "when there is a target" do
|
192
|
+
before do
|
193
|
+
TokenRefreshDummy.new_token = nil
|
194
|
+
client.token = auth_token
|
195
|
+
end
|
202
196
|
|
203
|
-
|
204
|
-
|
197
|
+
context "when the token refreshes" do
|
198
|
+
it "saves to the target file" do
|
199
|
+
TokenRefreshDummy.any_instance.stub(:target_info) { {} }
|
200
|
+
TokenRefreshDummy.any_instance.stub(:save_target_info).with(anything) do |info|
|
205
201
|
expect(info[:token]).to eq new_auth_token.auth_header
|
206
202
|
end
|
207
|
-
end
|
208
203
|
|
209
|
-
|
204
|
+
subject
|
205
|
+
end
|
210
206
|
end
|
211
|
-
end
|
212
207
|
|
213
|
-
|
214
|
-
|
208
|
+
context "but there is no token initially" do
|
209
|
+
let(:auth_token) { nil }
|
215
210
|
|
216
|
-
|
217
|
-
|
218
|
-
|
211
|
+
it "doesn't save the new token because something else probably did" do
|
212
|
+
context.should_not_receive(:save_target_info)
|
213
|
+
subject
|
214
|
+
end
|
219
215
|
end
|
220
|
-
end
|
221
216
|
|
222
|
-
|
223
|
-
|
217
|
+
context "and the token becomes nil" do
|
218
|
+
let(:new_auth_token) { nil }
|
224
219
|
|
225
|
-
|
226
|
-
|
227
|
-
|
220
|
+
it "doesn't save the nil token" do
|
221
|
+
context.should_not_receive(:save_target_info)
|
222
|
+
subject
|
223
|
+
end
|
228
224
|
end
|
229
225
|
end
|
230
|
-
end
|
231
226
|
|
232
|
-
|
233
|
-
|
227
|
+
context "when there is no target" do
|
228
|
+
let(:client) { nil }
|
234
229
|
|
235
|
-
|
236
|
-
|
230
|
+
it "doesn't try to compare the tokens" do
|
231
|
+
expect { subject }.to_not raise_error
|
232
|
+
end
|
237
233
|
end
|
238
234
|
end
|
239
235
|
end
|
240
|
-
end
|
241
|
-
|
242
|
-
describe '#log_error' do
|
243
|
-
subject do
|
244
|
-
context.log_error(exception)
|
245
|
-
File.read(File.expand_path(CF::CRASH_FILE))
|
246
|
-
end
|
247
236
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
error
|
237
|
+
describe "#log_error" do
|
238
|
+
subject do
|
239
|
+
context.log_error(exception)
|
240
|
+
File.read(File.expand_path(CF::CRASH_FILE))
|
253
241
|
end
|
254
242
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
243
|
+
context "when the exception is a normal error" do
|
244
|
+
let(:exception) do
|
245
|
+
error = StandardError.new("gemfiles are kinda hard")
|
246
|
+
error.set_backtrace(["fo/gems/bar", "baz quick"])
|
247
|
+
error
|
248
|
+
end
|
261
249
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
error.set_backtrace(["fo/gems/bar", "baz quick"])
|
268
|
-
error
|
250
|
+
it { should include "Time of crash:" }
|
251
|
+
it { should include "gemfiles are kinda hard" }
|
252
|
+
it { should include "bar" }
|
253
|
+
it { should_not include "fo/gems/bar" }
|
254
|
+
it { should include "baz quick" }
|
269
255
|
end
|
270
256
|
|
271
|
-
|
272
|
-
|
273
|
-
|
257
|
+
context "when the exception is an APIError" do
|
258
|
+
let(:request) { {:method => "GET", :url => "http://api.cloudfoundry.com/foo", :headers => {}, :body => nil} }
|
259
|
+
let(:response) { {:status => 404, :body => "bar", :headers => {}} }
|
260
|
+
let(:exception) do
|
261
|
+
error = CFoundry::APIError.new(nil, nil, request, response)
|
262
|
+
error.set_backtrace(["fo/gems/bar", "baz quick"])
|
263
|
+
error
|
264
|
+
end
|
265
|
+
|
266
|
+
before do
|
267
|
+
response.stub(:body) { "Response Body" }
|
268
|
+
end
|
274
269
|
|
275
|
-
|
276
|
-
|
270
|
+
it { should include "REQUEST: " }
|
271
|
+
it { should include "RESPONSE: " }
|
272
|
+
end
|
277
273
|
end
|
278
|
-
end
|
279
274
|
|
280
|
-
|
281
|
-
|
275
|
+
describe "#client_target" do
|
276
|
+
subject { context.client_target }
|
282
277
|
|
283
|
-
|
284
|
-
|
278
|
+
context "when a ~/.cf/target exists" do
|
279
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_home_dirs/new" }
|
285
280
|
|
286
|
-
|
287
|
-
|
281
|
+
it "returns the target in that file" do
|
282
|
+
expect(subject).to eq "https://api.some-domain.com"
|
283
|
+
end
|
288
284
|
end
|
289
|
-
end
|
290
285
|
|
291
|
-
|
292
|
-
|
286
|
+
context "when no target file exists" do
|
287
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_home_dirs/no_config" }
|
293
288
|
|
294
|
-
|
295
|
-
|
289
|
+
it "returns nil" do
|
290
|
+
expect(subject).to eq nil
|
291
|
+
end
|
296
292
|
end
|
297
293
|
end
|
298
|
-
end
|
299
294
|
|
300
|
-
|
301
|
-
|
295
|
+
describe "#targets_info" do
|
296
|
+
subject { context.targets_info }
|
302
297
|
|
303
|
-
|
304
|
-
|
298
|
+
context "when a ~/.cf/tokens.yml exists" do
|
299
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_home_dirs/new" }
|
305
300
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
301
|
+
it "returns the file's contents as a hash" do
|
302
|
+
expect(subject).to eq({
|
303
|
+
"https://api.some-domain.com" => {
|
304
|
+
:token => "bearer some-token",
|
305
|
+
:version => 2
|
306
|
+
}
|
307
|
+
})
|
308
|
+
end
|
313
309
|
end
|
314
|
-
end
|
315
310
|
|
316
|
-
|
317
|
-
|
311
|
+
context "when no token file exists" do
|
312
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_home_dirs/no_config" }
|
318
313
|
|
319
|
-
|
320
|
-
|
314
|
+
it "returns an empty hash" do
|
315
|
+
expect(subject).to eq({})
|
316
|
+
end
|
321
317
|
end
|
322
318
|
end
|
323
|
-
end
|
324
319
|
|
325
|
-
|
326
|
-
|
320
|
+
describe "#target_info" do
|
321
|
+
subject { CF::CLI.new.target_info("https://api.some-domain.com") }
|
327
322
|
|
328
|
-
|
329
|
-
|
323
|
+
context "when a ~/.cf/tokens.yml exists" do
|
324
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_home_dirs/new" }
|
330
325
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
326
|
+
it "returns the info for the given url" do
|
327
|
+
expect(subject).to eq({
|
328
|
+
:token => "bearer some-token",
|
329
|
+
:version => 2
|
330
|
+
})
|
331
|
+
end
|
336
332
|
end
|
337
|
-
end
|
338
333
|
|
339
|
-
|
340
|
-
|
334
|
+
context "when no token file exists" do
|
335
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_home_dirs/no_config" }
|
341
336
|
|
342
|
-
|
343
|
-
|
337
|
+
it "returns an empty hash" do
|
338
|
+
expect(subject).to eq({})
|
339
|
+
end
|
344
340
|
end
|
345
341
|
end
|
346
|
-
end
|
347
342
|
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
343
|
+
describe "methods that update the token info" do
|
344
|
+
before do
|
345
|
+
context.stub(:targets_info) do
|
346
|
+
{
|
347
|
+
"https://api.some-domain.com" => {:token => "bearer token1"},
|
348
|
+
"https://api.some-other-domain.com" => {:token => "bearer token2"}
|
349
|
+
}
|
350
|
+
end
|
355
351
|
end
|
356
|
-
end
|
357
352
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
353
|
+
describe "#save_target_info" do
|
354
|
+
it "adds the given target info, and writes the result to ~/.cf/tokens.yml" do
|
355
|
+
context.save_target_info({:token => "bearer token3"}, "https://api.some-domain.com")
|
356
|
+
YAML.load_file(File.expand_path("~/.cf/tokens.yml")).should == {
|
357
|
+
"https://api.some-domain.com" => {:token => "bearer token3"},
|
358
|
+
"https://api.some-other-domain.com" => {:token => "bearer token2"}
|
359
|
+
}
|
360
|
+
end
|
365
361
|
end
|
366
|
-
end
|
367
362
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
363
|
+
describe "#remove_target_info" do
|
364
|
+
it "removes the given target, and writes the result to ~/.cf/tokens.yml" do
|
365
|
+
context.remove_target_info("https://api.some-domain.com")
|
366
|
+
YAML.load_file(File.expand_path("~/.cf/tokens.yml")).should == {
|
367
|
+
"https://api.some-other-domain.com" => {:token => "bearer token2"}
|
368
|
+
}
|
369
|
+
end
|
374
370
|
end
|
375
371
|
end
|
376
|
-
end
|
377
372
|
|
378
|
-
|
379
|
-
|
373
|
+
describe "#client" do
|
374
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_home_dirs/new" }
|
380
375
|
|
381
|
-
|
376
|
+
before { context.stub(:input).and_return({}) }
|
382
377
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
378
|
+
describe "the client's token" do
|
379
|
+
it "constructs an AuthToken object with the data from the tokens.yml file" do
|
380
|
+
expect(context.client.token).to be_a(CFoundry::AuthToken)
|
381
|
+
expect(context.client.token.auth_header).to eq("bearer some-token")
|
382
|
+
end
|
388
383
|
|
389
|
-
|
390
|
-
|
391
|
-
|
384
|
+
it "does not assign an AuthToken on the client if there is no token stored" do
|
385
|
+
context.should_receive(:target_info).with("some-fake-target") { {:version => 2} }
|
386
|
+
expect(context.client("some-fake-target").token).to be_nil
|
387
|
+
end
|
392
388
|
end
|
393
|
-
end
|
394
389
|
|
395
|
-
|
396
|
-
|
397
|
-
|
390
|
+
describe "the client's version" do
|
391
|
+
it "uses the version stored in the yml file" do
|
392
|
+
expect(context.client.version).to eq(2)
|
393
|
+
end
|
398
394
|
end
|
399
|
-
end
|
400
395
|
|
401
|
-
|
402
|
-
|
396
|
+
context "when there is no target" do
|
397
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_home_dirs/no_config" }
|
403
398
|
|
404
|
-
|
405
|
-
|
399
|
+
it "returns nil" do
|
400
|
+
expect(context.client).to eq(nil)
|
401
|
+
end
|
406
402
|
end
|
407
|
-
end
|
408
403
|
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
404
|
+
context "with a cloud controller" do
|
405
|
+
before do
|
406
|
+
context.stub(:target_info) { {:version => 2} }
|
407
|
+
end
|
413
408
|
|
414
|
-
|
415
|
-
|
416
|
-
|
409
|
+
it "connects using the v2 api" do
|
410
|
+
expect(context.client).to be_a(CFoundry::V2::Client)
|
411
|
+
end
|
417
412
|
|
418
|
-
|
419
|
-
|
413
|
+
%w{https_proxy HTTPS_PROXY http_proxy HTTP_PROXY}.each do |variable|
|
414
|
+
proxy_name = variable.downcase.to_sym
|
420
415
|
|
421
|
-
|
422
|
-
|
423
|
-
|
416
|
+
context "when ENV['#{variable}'] is set" do
|
417
|
+
before { ENV[variable] = "http://lower.example.com:80" }
|
418
|
+
after { ENV.delete(variable) }
|
424
419
|
|
425
|
-
|
426
|
-
|
420
|
+
it "uses the #{proxy_name} proxy URI on the environment variable" do
|
421
|
+
expect(context.client.send(proxy_name)).to eq("http://lower.example.com:80")
|
422
|
+
end
|
427
423
|
end
|
428
424
|
end
|
429
|
-
end
|
430
425
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
426
|
+
context "when both input and environment variable are provided" do
|
427
|
+
before do
|
428
|
+
ENV["HTTPS_PROXY"] = "http://should.be.overwritten.example.com:80"
|
429
|
+
context.stub(:input) { {:https_proxy => "http://arg.example.com:80"} }
|
430
|
+
end
|
436
431
|
|
437
|
-
|
432
|
+
after { ENV.delete("HTTPS_PROXY") }
|
438
433
|
|
439
|
-
|
440
|
-
|
434
|
+
it "uses the provided https proxy URI" do
|
435
|
+
expect(context.client.https_proxy).to eq("http://arg.example.com:80")
|
436
|
+
end
|
441
437
|
end
|
442
438
|
end
|
443
439
|
end
|
444
440
|
end
|
445
441
|
end
|
446
|
-
|