cf 0.1.5 → 0.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. data/LICENSE +1277 -30
  2. data/Rakefile +12 -1
  3. data/bin/cf +0 -3
  4. data/lib/cf.rb +6 -0
  5. data/lib/cf/cli.rb +389 -190
  6. data/lib/cf/cli/app/app.rb +45 -0
  7. data/lib/cf/cli/app/apps.rb +99 -0
  8. data/lib/cf/cli/app/base.rb +90 -0
  9. data/lib/cf/cli/app/crashes.rb +42 -0
  10. data/lib/cf/cli/app/delete.rb +95 -0
  11. data/lib/cf/cli/app/deprecated.rb +11 -0
  12. data/lib/cf/cli/app/env.rb +78 -0
  13. data/lib/cf/cli/app/files.rb +137 -0
  14. data/lib/cf/cli/app/health.rb +26 -0
  15. data/lib/cf/cli/app/instances.rb +53 -0
  16. data/lib/cf/cli/app/logs.rb +76 -0
  17. data/lib/cf/cli/app/push.rb +105 -0
  18. data/lib/cf/cli/app/push/create.rb +149 -0
  19. data/lib/cf/cli/app/push/interactions.rb +94 -0
  20. data/lib/cf/cli/app/push/sync.rb +64 -0
  21. data/lib/cf/cli/app/rename.rb +35 -0
  22. data/lib/cf/cli/app/restart.rb +20 -0
  23. data/lib/cf/cli/app/scale.rb +69 -0
  24. data/lib/cf/cli/app/start.rb +143 -0
  25. data/lib/cf/cli/app/stats.rb +67 -0
  26. data/lib/cf/cli/app/stop.rb +27 -0
  27. data/lib/cf/cli/domain/base.rb +8 -0
  28. data/lib/cf/cli/domain/domains.rb +40 -0
  29. data/lib/cf/cli/domain/map.rb +55 -0
  30. data/lib/cf/cli/domain/unmap.rb +56 -0
  31. data/lib/cf/cli/help.rb +15 -0
  32. data/lib/cf/cli/interactive.rb +105 -0
  33. data/lib/cf/cli/organization/base.rb +12 -0
  34. data/lib/cf/cli/organization/create.rb +32 -0
  35. data/lib/cf/cli/organization/delete.rb +73 -0
  36. data/lib/cf/cli/organization/org.rb +45 -0
  37. data/lib/cf/cli/organization/orgs.rb +35 -0
  38. data/lib/cf/cli/organization/rename.rb +36 -0
  39. data/lib/cf/cli/route/base.rb +8 -0
  40. data/lib/cf/cli/route/map.rb +70 -0
  41. data/lib/cf/cli/route/routes.rb +26 -0
  42. data/lib/cf/cli/route/unmap.rb +62 -0
  43. data/lib/cf/cli/service/base.rb +8 -0
  44. data/lib/cf/cli/service/bind.rb +44 -0
  45. data/lib/cf/cli/service/create.rb +107 -0
  46. data/lib/cf/cli/service/delete.rb +82 -0
  47. data/lib/cf/cli/service/rename.rb +35 -0
  48. data/lib/cf/cli/service/service.rb +40 -0
  49. data/lib/cf/cli/service/services.rb +99 -0
  50. data/lib/cf/cli/service/unbind.rb +38 -0
  51. data/lib/cf/cli/space/base.rb +19 -0
  52. data/lib/cf/cli/space/create.rb +63 -0
  53. data/lib/cf/cli/space/delete.rb +95 -0
  54. data/lib/cf/cli/space/rename.rb +39 -0
  55. data/lib/cf/cli/space/space.rb +64 -0
  56. data/lib/cf/cli/space/spaces.rb +55 -0
  57. data/lib/cf/cli/space/switch.rb +16 -0
  58. data/lib/cf/cli/start/base.rb +93 -0
  59. data/lib/cf/cli/start/colors.rb +13 -0
  60. data/lib/cf/cli/start/info.rb +124 -0
  61. data/lib/cf/cli/start/login.rb +94 -0
  62. data/lib/cf/cli/start/logout.rb +17 -0
  63. data/lib/cf/cli/start/target.rb +69 -0
  64. data/lib/cf/cli/start/target_interactions.rb +37 -0
  65. data/lib/cf/cli/start/targets.rb +16 -0
  66. data/lib/cf/cli/user/base.rb +29 -0
  67. data/lib/cf/cli/user/create.rb +39 -0
  68. data/lib/cf/cli/user/passwd.rb +43 -0
  69. data/lib/cf/cli/user/register.rb +42 -0
  70. data/lib/cf/cli/user/users.rb +32 -0
  71. data/lib/cf/constants.rb +10 -7
  72. data/lib/cf/detect.rb +113 -48
  73. data/lib/cf/errors.rb +17 -0
  74. data/lib/cf/plugin.rb +28 -12
  75. data/lib/cf/spacing.rb +89 -0
  76. data/lib/cf/spec_helper.rb +1 -0
  77. data/lib/cf/test_support.rb +6 -0
  78. data/lib/cf/version.rb +1 -1
  79. data/spec/assets/hello-sinatra/Gemfile +3 -0
  80. data/spec/assets/hello-sinatra/Gemfile.lock +17 -0
  81. data/spec/assets/hello-sinatra/config.ru +3 -0
  82. data/spec/assets/hello-sinatra/fat-cat-makes-app-larger.png +0 -0
  83. data/spec/assets/hello-sinatra/main.rb +6 -0
  84. data/spec/assets/specker_runner/specker_runner_input.rb +6 -0
  85. data/spec/assets/specker_runner/specker_runner_pause.rb +5 -0
  86. data/spec/cf/cli/app/base_spec.rb +17 -0
  87. data/spec/cf/cli/app/delete_spec.rb +188 -0
  88. data/spec/cf/cli/app/instances_spec.rb +65 -0
  89. data/spec/cf/cli/app/push/create_spec.rb +661 -0
  90. data/spec/cf/cli/app/push_spec.rb +369 -0
  91. data/spec/cf/cli/app/rename_spec.rb +104 -0
  92. data/spec/cf/cli/app/scale_spec.rb +75 -0
  93. data/spec/cf/cli/app/start_spec.rb +208 -0
  94. data/spec/cf/cli/app/stats_spec.rb +68 -0
  95. data/spec/cf/cli/domain/map_spec.rb +130 -0
  96. data/spec/cf/cli/domain/unmap_spec.rb +69 -0
  97. data/spec/cf/cli/organization/orgs_spec.rb +108 -0
  98. data/spec/cf/cli/organization/rename_spec.rb +113 -0
  99. data/spec/cf/cli/route/map_spec.rb +121 -0
  100. data/spec/cf/cli/route/unmap_spec.rb +155 -0
  101. data/spec/cf/cli/service/bind_spec.rb +25 -0
  102. data/spec/cf/cli/service/delete_spec.rb +22 -0
  103. data/spec/cf/cli/service/rename_spec.rb +105 -0
  104. data/spec/cf/cli/service/service_spec.rb +23 -0
  105. data/spec/cf/cli/service/unbind_spec.rb +25 -0
  106. data/spec/cf/cli/space/create_spec.rb +93 -0
  107. data/spec/cf/cli/space/rename_spec.rb +102 -0
  108. data/spec/cf/cli/space/spaces_spec.rb +104 -0
  109. data/spec/cf/cli/space/switch_space_spec.rb +55 -0
  110. data/spec/cf/cli/start/info_spec.rb +160 -0
  111. data/spec/cf/cli/start/login_spec.rb +142 -0
  112. data/spec/cf/cli/start/logout_spec.rb +50 -0
  113. data/spec/cf/cli/start/target_spec.rb +123 -0
  114. data/spec/cf/cli/user/create_spec.rb +54 -0
  115. data/spec/cf/cli/user/passwd_spec.rb +102 -0
  116. data/spec/cf/cli/user/register_spec.rb +140 -0
  117. data/spec/cf/cli_spec.rb +442 -0
  118. data/spec/cf/detect_spec.rb +54 -0
  119. data/spec/console_app_specker/console_app_specker_matchers_spec.rb +173 -0
  120. data/spec/console_app_specker/specker_runner_spec.rb +167 -0
  121. data/spec/features/account_lifecycle_spec.rb +85 -0
  122. data/spec/features/login_spec.rb +66 -0
  123. data/spec/features/push_flow_spec.rb +125 -0
  124. data/spec/features/switching_targets_spec.rb +32 -0
  125. data/spec/spec_helper.rb +72 -0
  126. data/spec/support/command_helper.rb +81 -0
  127. data/spec/support/config_helper.rb +15 -0
  128. data/spec/support/console_app_specker_matchers.rb +86 -0
  129. data/spec/support/fake_home_dir.rb +55 -0
  130. data/spec/support/interact_helper.rb +29 -0
  131. data/spec/support/shared_examples/errors.rb +40 -0
  132. data/spec/support/shared_examples/input.rb +14 -0
  133. data/spec/support/specker_runner.rb +80 -0
  134. data/spec/support/tracking_expector.rb +71 -0
  135. metadata +427 -66
  136. data/lib/cf/cli/app.rb +0 -595
  137. data/lib/cf/cli/command.rb +0 -444
  138. data/lib/cf/cli/dots.rb +0 -133
  139. data/lib/cf/cli/service.rb +0 -112
  140. data/lib/cf/cli/user.rb +0 -71
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+ require "cf/cli/space/switch"
3
+
4
+ describe CF::Space::Switch do
5
+ let(:space_to_switch_to) { spaces.last }
6
+ let(:spaces) { fake_list(:space, 3) }
7
+ let(:organization) { fake(:organization, :spaces => spaces) }
8
+ let(:client) { fake_client(:current_organization => organization, :spaces => spaces) }
9
+
10
+ before do
11
+ any_instance_of described_class do |cli|
12
+ stub(cli).client { client }
13
+ stub(cli).precondition { nil }
14
+ end
15
+ end
16
+
17
+ describe 'metadata' do
18
+ let(:command) { Mothership.commands[:switch_space] }
19
+
20
+ describe 'command' do
21
+ subject { command }
22
+ its(:description) { should eq "Switch to a space" }
23
+ it { expect(Mothership::Help.group(:spaces)).to include(subject) }
24
+ end
25
+
26
+ include_examples 'inputs must have descriptions'
27
+
28
+ describe 'arguments' do
29
+ subject { command.arguments }
30
+ it 'has the correct argument order' do
31
+ should eq([{ :type => :normal, :value => nil, :name => :name }])
32
+ end
33
+ end
34
+ end
35
+
36
+ subject { cf %W[--no-quiet switch-space #{space_to_switch_to.name} --no-color] }
37
+
38
+ context "when the space exists" do
39
+ it "switches to that space" do
40
+ any_instance_of(Mothership) do |m|
41
+ mock(m).invoke(:target, {:space => space_to_switch_to})
42
+ end
43
+
44
+ subject
45
+ end
46
+ end
47
+
48
+ context "when the space does not exist" do
49
+ let(:space_to_switch_to) { fake(:space, :name => "unique-name") }
50
+
51
+ it_behaves_like "an error that gets passed through",
52
+ :with_exception => CF::UserError,
53
+ :with_message => "The space unique-name does not exist, please create the space first."
54
+ end
55
+ end
@@ -0,0 +1,160 @@
1
+ require 'spec_helper'
2
+
3
+ describe CF::Start::Info do
4
+ let(:frameworks) { false }
5
+ let(:runtimes) { false }
6
+ let(:services) { false }
7
+ let(:all) { false }
8
+
9
+ let(:client) do
10
+ fake_client :frameworks => fake_list(:framework, 3),
11
+ :runtimes => fake_list(:runtime, 3),
12
+ :services => fake_list(:service, 3),
13
+ :token => CFoundry::AuthToken.new("bearer some-access-token")
14
+ end
15
+
16
+ let(:target_info) do
17
+ { :description => "Some description",
18
+ :version => 2,
19
+ :support => "http://example.com"
20
+ }
21
+ end
22
+
23
+ before do
24
+ any_instance_of described_class do |cli|
25
+ stub(cli).client { client }
26
+ end
27
+ end
28
+
29
+ describe 'metadata' do
30
+ let(:command) { Mothership.commands[:info] }
31
+
32
+ describe 'command' do
33
+ subject { command }
34
+ its(:description) { should eq "Display information on the current target, user, etc." }
35
+ it { expect(Mothership::Help.group(:start)).to include(subject) }
36
+ end
37
+
38
+ include_examples 'inputs must have descriptions'
39
+
40
+ describe 'flags' do
41
+ subject { command.flags }
42
+
43
+ its(["-f"]) { should eq :frameworks }
44
+ its(["-r"]) { should eq :runtimes }
45
+ its(["-s"]) { should eq :services }
46
+ its(["-a"]) { should eq :all }
47
+ end
48
+
49
+ describe 'arguments' do
50
+ subject { command.arguments }
51
+ it { should be_empty }
52
+ end
53
+ end
54
+
55
+
56
+ subject { cf %W[info --#{bool_flag(:frameworks)} --#{bool_flag(:runtimes)} --#{bool_flag(:services)} --#{bool_flag(:all)} --no-force --no-quiet] }
57
+
58
+ context 'when given no flags' do
59
+ it "displays target information" do
60
+ mock(client).info { target_info }
61
+
62
+ subject
63
+
64
+ stdout.rewind
65
+ expect(stdout.readline).to eq "Some description\n"
66
+ expect(stdout.readline).to eq "\n"
67
+ expect(stdout.readline).to eq "target: #{client.target}\n"
68
+ expect(stdout.readline).to eq " version: 2\n"
69
+ expect(stdout.readline).to eq " support: http://example.com\n"
70
+ end
71
+ end
72
+
73
+ context 'when given --frameworks' do
74
+ let(:frameworks) { true }
75
+
76
+ it 'does not grab /info' do
77
+ dont_allow(client).info
78
+ subject
79
+ end
80
+
81
+ it 'lists frameworks on the target' do
82
+ subject
83
+
84
+ stdout.rewind
85
+ expect(stdout.readline).to match /Getting frameworks.*OK/
86
+ expect(stdout.readline).to eq "\n"
87
+ expect(stdout.readline).to match /framework\s+description/
88
+
89
+ client.frameworks.sort_by(&:name).each do |f|
90
+ expect(stdout.readline).to match /#{f.name}\s+#{f.description}/
91
+ end
92
+ end
93
+ end
94
+
95
+ context 'when given --runtimes' do
96
+ let(:runtimes) { true }
97
+
98
+ it 'does not grab /info' do
99
+ dont_allow(client).info
100
+ subject
101
+ end
102
+
103
+ it 'lists runtimes on the target' do
104
+ subject
105
+
106
+ stdout.rewind
107
+ expect(stdout.readline).to match /Getting runtimes.*OK/
108
+ expect(stdout.readline).to eq "\n"
109
+ expect(stdout.readline).to match /runtime\s+description/
110
+
111
+ client.runtimes.sort_by(&:name).each do |r|
112
+ expect(stdout.readline).to match /#{r.name}\s+#{r.description}/
113
+ end
114
+ end
115
+ end
116
+
117
+ context 'when given --services' do
118
+ let(:services) { true }
119
+
120
+ it 'does not grab /info' do
121
+ dont_allow(client).info
122
+ subject
123
+ end
124
+
125
+ it 'lists services on the target' do
126
+ subject
127
+
128
+ stdout.rewind
129
+ expect(stdout.readline).to match /Getting services.*OK/
130
+ expect(stdout.readline).to eq "\n"
131
+ expect(stdout.readline).to match /service\s+version\s+provider\s+plans\s+description/
132
+
133
+ client.services.sort_by(&:label).each do |s|
134
+ expect(stdout.readline).to match /#{s.label}\s+#{s.version}\s+#{s.provider}.+#{s.description}/
135
+ end
136
+ end
137
+ end
138
+
139
+ context 'when given --all' do
140
+ let(:all) { true }
141
+
142
+ it 'combines --frameworks --runtimes and --services' do
143
+ mock(client).info { target_info }
144
+
145
+ subject
146
+
147
+ stdout.rewind
148
+ expect(stdout.readline).to match /Getting runtimes.*OK/
149
+ expect(stdout.readline).to match /Getting frameworks.*OK/
150
+ expect(stdout.readline).to match /Getting services.*OK/
151
+ end
152
+ end
153
+
154
+ context 'when there is no target' do
155
+ let(:client) { nil }
156
+ it_behaves_like "an error that gets passed through",
157
+ :with_exception => CF::UserError,
158
+ :with_message => "Please select a target with 'cf target'."
159
+ end
160
+ end
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+
3
+ command CF::Start::Login do
4
+ let(:client) { fake_client :organizations => [] }
5
+
6
+ describe 'metadata' do
7
+ let(:command) { Mothership.commands[:login] }
8
+
9
+ describe 'command' do
10
+ subject { command }
11
+ its(:description) { should eq "Authenticate with the target" }
12
+ specify { expect(Mothership::Help.group(:start)).to include(subject) }
13
+ end
14
+
15
+ include_examples 'inputs must have descriptions'
16
+
17
+ describe 'flags' do
18
+ subject { command.flags }
19
+
20
+ its(["-o"]) { should eq :organization }
21
+ its(["--org"]) { should eq :organization }
22
+ its(["--email"]) { should eq :username }
23
+ its(["-s"]) { should eq :space }
24
+ end
25
+
26
+ describe 'arguments' do
27
+ subject(:arguments) { command.arguments }
28
+ it 'have the correct commands' do
29
+ expect(arguments).to eq [{:type => :optional, :value => :email, :name => :username}]
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "running the command" do
35
+ stub_home_dir_with { "#{SPEC_ROOT}/fixtures/fake_home_dirs/new" }
36
+
37
+ let(:auth_token) { CFoundry::AuthToken.new("bearer some-new-access-token", "some-new-refresh-token") }
38
+ let(:tokens_yaml) { YAML.load_file(File.expand_path(tokens_file_path)) }
39
+ let(:tokens_file_path) { '~/.cf/tokens.yml' }
40
+ let(:organizations) { [] }
41
+
42
+ before do
43
+ stub(client).login("my-username", "my-password") { auth_token }
44
+ stub(client).login_prompts do
45
+ {
46
+ :username => ["text", "Username"],
47
+ :password => ["password", "8-digit PIN"]
48
+ }
49
+ end
50
+ end
51
+
52
+ subject { cf ["login"] }
53
+
54
+ it "logs in with the provided credentials and saves the token data to the YAML file" do
55
+ stub_ask("Username", {}) { "my-username" }
56
+ stub_ask("8-digit PIN", {:echo => "*", :forget => true}) { "my-password" }
57
+
58
+ subject
59
+
60
+ expect(tokens_yaml["https://api.some-domain.com"][:token]).to eq("bearer some-new-access-token")
61
+ expect(tokens_yaml["https://api.some-domain.com"][:refresh_token]).to eq("some-new-refresh-token")
62
+ end
63
+
64
+ context "with space and org in the token file" do
65
+ before do
66
+ write_token_file(:space => "space-id-1", :organization => "organization-id-1")
67
+ stub_ask("Username", {}) { "my-username" }
68
+ stub_ask("8-digit PIN", {:echo => "*", :forget => true}) { "my-password" }
69
+ end
70
+
71
+ context "when the user has no organizations" do
72
+ it "clears the org and space param from the token file" do
73
+ subject
74
+
75
+ expect(tokens_yaml["https://api.some-domain.com"][:space]).to be_nil
76
+ expect(tokens_yaml["https://api.some-domain.com"][:organization]).to be_nil
77
+ end
78
+ end
79
+
80
+ context "when the user has an organization, but no spaces" do
81
+ let(:client) {
82
+ fake_client :organizations => organizations,
83
+ :token => CFoundry::AuthToken.new("bearer some-access-token")
84
+ }
85
+ let(:organization) { fake :organization, :users => [user] }
86
+ let(:user) { fake :user }
87
+
88
+ shared_examples_for :method_clearing_the_token_file do
89
+ it "sets the new organization in the token file" do
90
+ subject
91
+ expect(tokens_yaml["https://api.some-domain.com"][:organization]).to eq(organizations.first.guid)
92
+ end
93
+
94
+ it "clears the space param from the token file" do
95
+ subject
96
+ expect(tokens_yaml["https://api.some-domain.com"][:space]).to be_nil
97
+ end
98
+ end
99
+
100
+ context "with one organization" do
101
+ let(:organizations) {
102
+ [ organization ]
103
+ }
104
+
105
+ it "does not prompt for an organization" do
106
+ dont_allow_ask("Organization", anything)
107
+ subject
108
+ end
109
+
110
+ it_behaves_like :method_clearing_the_token_file
111
+ end
112
+
113
+ context "with multiple organizations" do
114
+ let(:organizations) {
115
+ [ organization, OpenStruct.new(:name => 'My Org 2', :guid => 'organization-id-2') ]
116
+ }
117
+
118
+ before do
119
+ stub_ask("Organization", anything) { organizations.first }
120
+ end
121
+
122
+ it "prompts for organization" do
123
+ mock_ask("Organization", anything) { organizations.first }
124
+ subject
125
+ end
126
+
127
+ it_behaves_like :method_clearing_the_token_file
128
+ end
129
+ end
130
+ end
131
+
132
+ context 'when there is no target' do
133
+ let(:client) { nil }
134
+ let(:stub_precondition?) { false }
135
+
136
+ it "tells the user to select a target" do
137
+ subject
138
+ expect(error_output).to say("Please select a target with 'cf target'.")
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe CF::Start::Logout do
4
+ let(:client) { fake_client }
5
+
6
+ before do
7
+ any_instance_of described_class do |cli|
8
+ stub(cli).client { client }
9
+ end
10
+ end
11
+
12
+ describe 'metadata' do
13
+ let(:command) { Mothership.commands[:logout] }
14
+
15
+ describe 'command' do
16
+ subject { command }
17
+ its(:description) { should eq "Log out from the target" }
18
+ it { expect(Mothership::Help.group(:start)).to include(subject) }
19
+ end
20
+ end
21
+
22
+ describe "running the command" do
23
+ subject { cf ["logout"] }
24
+
25
+ context "when there is a target" do
26
+ let(:info) { { client.target => "x", "abc" => "x" } }
27
+
28
+ before do
29
+ any_instance_of CF::CLI do |cli|
30
+ stub(cli).targets_info { info }
31
+ stub(cli).client_target { client.target }
32
+ end
33
+ end
34
+
35
+ it "removes the target info from the tokens file" do
36
+ expect {
37
+ subject
38
+ }.to change { info }.to("abc" => "x")
39
+ end
40
+ end
41
+
42
+ context "when there is no target" do
43
+ let(:client) { nil }
44
+ it_behaves_like "an error that gets passed through",
45
+ :with_exception => CF::UserError,
46
+ :with_message => "Please select a target with 'cf target'."
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+ require "webmock/rspec"
3
+
4
+ command CF::Start::Target do
5
+ let(:client) { fake_client :apps => [app] }
6
+ let(:app) { fake :app }
7
+
8
+ describe 'metadata' do
9
+ let(:command) { Mothership.commands[:target] }
10
+
11
+ describe 'command' do
12
+ subject { command }
13
+ its(:description) { should eq "Set or display the target cloud, organization, and space" }
14
+ specify { expect(Mothership::Help.group(:start)).to include(subject) }
15
+ end
16
+
17
+ include_examples 'inputs must have descriptions'
18
+
19
+ describe 'flags' do
20
+ subject { command.flags }
21
+
22
+ its(["-o"]) { should eq :organization }
23
+ its(["--org"]) { should eq :organization }
24
+ its(["-s"]) { should eq :space }
25
+ end
26
+
27
+ describe 'arguments' do
28
+ subject(:arguments) { command.arguments }
29
+ it 'have the correct commands' do
30
+ expect(arguments).to eq [{:type => :optional, :value => nil, :name => :url}]
31
+ end
32
+ end
33
+ end
34
+
35
+ describe 'running the command' do
36
+ stub_home_dir_with { "#{SPEC_ROOT}/fixtures/fake_home_dirs/new" }
37
+
38
+ context "when the user is authenticated and has an organization" do
39
+ let(:tokens_file_path) { '~/.cf/tokens.yml' }
40
+ let(:organizations) {
41
+ [ fake(:organization, :name => 'My Org', :guid => 'organization-id-1', :users => [user], :spaces => spaces),
42
+ fake(:organization, :name => 'My Org 2', :guid => 'organization-id-2') ]
43
+ }
44
+ let(:spaces) {
45
+ [ fake(:space, :name => 'Development', :guid => 'space-id-1'),
46
+ fake(:space, :name => 'Staging', :guid => 'space-id-2') ]
47
+ }
48
+
49
+ let(:user) { stub! }
50
+ let(:organization) { organizations.first }
51
+ let(:client) do
52
+ fake_client :frameworks => fake_list(:framework, 3),
53
+ :organizations => organizations,
54
+ :token => CFoundry::AuthToken.new("bearer some-access-token")
55
+ end
56
+
57
+ before do
58
+ write_token_file({:space => "space-id-1", :organization => "organization-id-1"})
59
+ stub(client).current_user { user }
60
+ stub(client).organization { organization }
61
+ stub(client).current_organization { organization }
62
+ any_instance_of(described_class) do |instance|
63
+ stub(instance).client { client }
64
+ end
65
+ end
66
+
67
+ describe "switching the target" do
68
+ let(:target) { "some-valid-target.com" }
69
+ subject { cf ["target", target] }
70
+
71
+ context "when the target is not valid" do
72
+ before { WebMock.stub_request(:get, "http://#{target}/info").to_return(:body => "{}") }
73
+
74
+ it "should still be able to switch to a valid target after that" do
75
+ subject
76
+ end
77
+ end
78
+
79
+ context "when the target is valid but the connection is refused" do
80
+ it "shows a pretty error message" do
81
+ any_instance_of(CFoundry::Client) do |cli|
82
+ stub(cli).info { raise CFoundry::TargetRefused, "foo" }
83
+ end
84
+
85
+ subject
86
+ expect(error_output).to say("Target refused connection.")
87
+ end
88
+ end
89
+
90
+ context "when the uri is malformed" do
91
+ it "shows a pretty error message" do
92
+ any_instance_of(CFoundry::Client) do |cli|
93
+ stub(cli).info { raise CFoundry::InvalidTarget.new(target) }
94
+ end
95
+
96
+ subject
97
+ expect(error_output).to say("Invalid target URI.")
98
+ end
99
+ end
100
+ end
101
+
102
+ describe "switching the space" do
103
+ let(:space) { spaces.last }
104
+ let(:tokens_yaml) { YAML.load_file(File.expand_path(tokens_file_path)) }
105
+ let(:tokens_file_path) { '~/.cf/tokens.yml' }
106
+
107
+ def run_command
108
+ cf %W[target -s #{space.name}]
109
+ end
110
+
111
+ it "should not reprompt for organization" do
112
+ dont_allow_ask("Organization", anything)
113
+ run_command
114
+ end
115
+
116
+ it "sets the space param in the token file" do
117
+ run_command
118
+ expect(tokens_yaml["https://api.some-domain.com"][:space]).to be == 'space-id-2'
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end