af 0.3.22 → 0.5.0.beta.1

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.
Files changed (157) hide show
  1. checksums.yaml +14 -6
  2. data/LICENSE +1277 -24
  3. data/Rakefile +24 -87
  4. data/bin/af +7 -2
  5. data/lib/af/version.rb +3 -0
  6. data/lib/vmc.rb +7 -2
  7. data/lib/vmc/cli.rb +475 -0
  8. data/lib/vmc/cli/app/app.rb +45 -0
  9. data/lib/vmc/cli/app/apps.rb +105 -0
  10. data/lib/vmc/cli/app/base.rb +82 -0
  11. data/lib/vmc/cli/app/crashes.rb +46 -0
  12. data/lib/vmc/cli/app/delete.rb +95 -0
  13. data/lib/vmc/cli/app/deprecated.rb +11 -0
  14. data/lib/vmc/cli/app/env.rb +78 -0
  15. data/lib/vmc/cli/app/files.rb +137 -0
  16. data/lib/vmc/cli/app/health.rb +26 -0
  17. data/lib/vmc/cli/app/instances.rb +53 -0
  18. data/lib/vmc/cli/app/logs.rb +76 -0
  19. data/lib/vmc/cli/app/push.rb +107 -0
  20. data/lib/vmc/cli/app/push/create.rb +150 -0
  21. data/lib/vmc/cli/app/push/interactions.rb +100 -0
  22. data/lib/vmc/cli/app/push/sync.rb +64 -0
  23. data/lib/vmc/cli/app/rename.rb +39 -0
  24. data/lib/vmc/cli/app/restart.rb +20 -0
  25. data/lib/vmc/cli/app/scale.rb +71 -0
  26. data/lib/vmc/cli/app/start.rb +93 -0
  27. data/lib/vmc/cli/app/stats.rb +67 -0
  28. data/lib/vmc/cli/app/stop.rb +27 -0
  29. data/lib/vmc/cli/domain/base.rb +12 -0
  30. data/lib/vmc/cli/domain/domains.rb +40 -0
  31. data/lib/vmc/cli/domain/map.rb +55 -0
  32. data/lib/vmc/cli/domain/unmap.rb +56 -0
  33. data/lib/vmc/cli/help.rb +16 -0
  34. data/lib/vmc/cli/interactive.rb +105 -0
  35. data/lib/vmc/cli/organization/base.rb +14 -0
  36. data/lib/vmc/cli/organization/create.rb +32 -0
  37. data/lib/vmc/cli/organization/delete.rb +73 -0
  38. data/lib/vmc/cli/organization/org.rb +45 -0
  39. data/lib/vmc/cli/organization/orgs.rb +35 -0
  40. data/lib/vmc/cli/organization/rename.rb +36 -0
  41. data/lib/vmc/cli/route/base.rb +12 -0
  42. data/lib/vmc/cli/route/map.rb +80 -0
  43. data/lib/vmc/cli/route/routes.rb +26 -0
  44. data/lib/vmc/cli/route/unmap.rb +94 -0
  45. data/lib/vmc/cli/service/base.rb +8 -0
  46. data/lib/vmc/cli/service/bind.rb +44 -0
  47. data/lib/vmc/cli/service/create.rb +126 -0
  48. data/lib/vmc/cli/service/delete.rb +86 -0
  49. data/lib/vmc/cli/service/rename.rb +35 -0
  50. data/lib/vmc/cli/service/service.rb +42 -0
  51. data/lib/vmc/cli/service/services.rb +115 -0
  52. data/lib/vmc/cli/service/unbind.rb +38 -0
  53. data/lib/vmc/cli/space/base.rb +21 -0
  54. data/lib/vmc/cli/space/create.rb +56 -0
  55. data/lib/vmc/cli/space/delete.rb +95 -0
  56. data/lib/vmc/cli/space/rename.rb +39 -0
  57. data/lib/vmc/cli/space/space.rb +64 -0
  58. data/lib/vmc/cli/space/spaces.rb +55 -0
  59. data/lib/vmc/cli/space/take.rb +16 -0
  60. data/lib/vmc/cli/start/base.rb +80 -0
  61. data/lib/vmc/cli/start/colors.rb +13 -0
  62. data/lib/vmc/cli/start/info.rb +122 -0
  63. data/lib/vmc/cli/start/login.rb +92 -0
  64. data/lib/vmc/cli/start/logout.rb +13 -0
  65. data/lib/vmc/cli/start/target.rb +64 -0
  66. data/lib/vmc/cli/start/target_interactions.rb +37 -0
  67. data/lib/vmc/cli/start/targets.rb +16 -0
  68. data/lib/vmc/cli/user/base.rb +29 -0
  69. data/lib/vmc/cli/user/create.rb +39 -0
  70. data/lib/vmc/cli/user/delete.rb +25 -0
  71. data/lib/vmc/cli/user/passwd.rb +50 -0
  72. data/lib/vmc/cli/user/register.rb +42 -0
  73. data/lib/vmc/cli/user/users.rb +32 -0
  74. data/lib/vmc/constants.rb +13 -0
  75. data/lib/vmc/detect.rb +134 -0
  76. data/lib/vmc/errors.rb +17 -0
  77. data/lib/vmc/plugin.rb +56 -0
  78. data/lib/vmc/spacing.rb +89 -0
  79. data/lib/vmc/spec_helper.rb +1 -0
  80. data/lib/vmc/test_support.rb +4 -0
  81. data/lib/vmc/test_support/command_helper.rb +32 -0
  82. data/lib/vmc/test_support/common_input_examples.rb +14 -0
  83. data/lib/vmc/test_support/fake_home_dir.rb +16 -0
  84. data/lib/vmc/test_support/interact_helper.rb +29 -0
  85. data/lib/vmc/version.rb +3 -0
  86. data/spec/assets/hello-sinatra/Gemfile +3 -0
  87. data/spec/assets/hello-sinatra/main.rb +6 -0
  88. data/spec/features/new_user_flow_spec.rb +71 -0
  89. data/spec/spec_helper.rb +63 -0
  90. data/spec/vmc/cli/app/base_spec.rb +17 -0
  91. data/spec/vmc/cli/app/delete_spec.rb +188 -0
  92. data/spec/vmc/cli/app/instances_spec.rb +65 -0
  93. data/spec/vmc/cli/app/push/create_spec.rb +571 -0
  94. data/spec/vmc/cli/app/push_spec.rb +369 -0
  95. data/spec/vmc/cli/app/rename_spec.rb +104 -0
  96. data/spec/vmc/cli/app/scale_spec.rb +81 -0
  97. data/spec/vmc/cli/app/stats_spec.rb +62 -0
  98. data/spec/vmc/cli/domain/map_spec.rb +140 -0
  99. data/spec/vmc/cli/domain/unmap_spec.rb +73 -0
  100. data/spec/vmc/cli/organization/orgs_spec.rb +108 -0
  101. data/spec/vmc/cli/organization/rename_spec.rb +113 -0
  102. data/spec/vmc/cli/route/map_spec.rb +138 -0
  103. data/spec/vmc/cli/route/unmap_spec.rb +215 -0
  104. data/spec/vmc/cli/service/bind_spec.rb +25 -0
  105. data/spec/vmc/cli/service/delete_spec.rb +22 -0
  106. data/spec/vmc/cli/service/rename_spec.rb +105 -0
  107. data/spec/vmc/cli/service/service_spec.rb +23 -0
  108. data/spec/vmc/cli/service/unbind_spec.rb +25 -0
  109. data/spec/vmc/cli/space/rename_spec.rb +102 -0
  110. data/spec/vmc/cli/space/spaces_spec.rb +104 -0
  111. data/spec/vmc/cli/start/info_spec.rb +153 -0
  112. data/spec/vmc/cli/start/login_spec.rb +71 -0
  113. data/spec/vmc/cli/user/create_spec.rb +54 -0
  114. data/spec/vmc/cli/user/passwd_spec.rb +102 -0
  115. data/spec/vmc/cli/user/register_spec.rb +148 -0
  116. data/spec/vmc/cli_spec.rb +448 -0
  117. data/spec/vmc/detect_spec.rb +54 -0
  118. metadata +231 -124
  119. data/README.md +0 -155
  120. data/caldecott_helper/Gemfile +0 -10
  121. data/caldecott_helper/Gemfile.lock +0 -48
  122. data/caldecott_helper/server.rb +0 -43
  123. data/config/clients.yml +0 -17
  124. data/config/micro/offline.conf +0 -2
  125. data/config/micro/paths.yml +0 -22
  126. data/config/micro/refresh_ip.rb +0 -20
  127. data/lib/cli.rb +0 -48
  128. data/lib/cli/commands/admin.rb +0 -81
  129. data/lib/cli/commands/apps.rb +0 -1358
  130. data/lib/cli/commands/base.rb +0 -233
  131. data/lib/cli/commands/manifest.rb +0 -56
  132. data/lib/cli/commands/micro.rb +0 -115
  133. data/lib/cli/commands/misc.rb +0 -147
  134. data/lib/cli/commands/services.rb +0 -217
  135. data/lib/cli/commands/user.rb +0 -70
  136. data/lib/cli/config.rb +0 -176
  137. data/lib/cli/console_helper.rb +0 -163
  138. data/lib/cli/core_ext.rb +0 -122
  139. data/lib/cli/errors.rb +0 -19
  140. data/lib/cli/file_helper.rb +0 -123
  141. data/lib/cli/frameworks.rb +0 -265
  142. data/lib/cli/manifest_helper.rb +0 -316
  143. data/lib/cli/runner.rb +0 -633
  144. data/lib/cli/services_helper.rb +0 -104
  145. data/lib/cli/tunnel_helper.rb +0 -336
  146. data/lib/cli/usage.rb +0 -129
  147. data/lib/cli/version.rb +0 -7
  148. data/lib/cli/zip_util.rb +0 -102
  149. data/lib/vmc/client.rb +0 -574
  150. data/lib/vmc/const.rb +0 -27
  151. data/lib/vmc/micro.rb +0 -56
  152. data/lib/vmc/micro/switcher/base.rb +0 -97
  153. data/lib/vmc/micro/switcher/darwin.rb +0 -19
  154. data/lib/vmc/micro/switcher/dummy.rb +0 -15
  155. data/lib/vmc/micro/switcher/linux.rb +0 -16
  156. data/lib/vmc/micro/switcher/windows.rb +0 -31
  157. data/lib/vmc/micro/vmrun.rb +0 -158
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+ require "vmc/cli/organization/rename"
3
+
4
+ describe VMC::Organization::Rename do
5
+ let(:global) { { :color => false, :quiet => true } }
6
+ let(:inputs) { {} }
7
+ let(:given) { {} }
8
+ let(:organizations) { fake_list(:organization, 3) }
9
+ let(:client) { fake_client(:organizations => organizations) }
10
+ let(:new_name) { "some-new-name" }
11
+
12
+ before do
13
+ any_instance_of(VMC::CLI) do |cli|
14
+ stub(cli).client { client }
15
+ stub(cli).precondition { nil }
16
+ end
17
+ end
18
+
19
+ subject { Mothership.new.invoke(:rename_org, inputs, given, global) }
20
+
21
+ describe 'metadata' do
22
+ let(:command) { Mothership.commands[:rename_org] }
23
+
24
+ describe 'command' do
25
+ subject { command }
26
+ its(:description) { should eq "Rename an organization" }
27
+ it { expect(Mothership::Help.group(:organizations)).to include(subject) }
28
+ end
29
+
30
+ describe 'inputs' do
31
+ subject { command.inputs }
32
+
33
+ it "is not missing any descriptions" do
34
+ subject.each do |input, attrs|
35
+ expect(attrs[:description]).to be
36
+ expect(attrs[:description].strip).to_not be_empty
37
+ end
38
+ end
39
+ end
40
+
41
+ describe 'arguments' do
42
+ subject { command.arguments }
43
+ it 'has the correct argument order' do
44
+ should eq([
45
+ { :type => :optional, :value => nil, :name => :organization },
46
+ { :type => :optional, :value => nil, :name => :name }
47
+ ])
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'when there are no organizations' do
53
+ let(:organizations) { [] }
54
+
55
+ context 'and an organization is given' do
56
+ let(:given) { { :organization => "some-invalid-organization" } }
57
+ it { expect { subject }.to raise_error(VMC::UserError, "Unknown organization 'some-invalid-organization'.") }
58
+ end
59
+
60
+ context 'and an organization is not given' do
61
+ it { expect { subject }.to raise_error(VMC::UserError, "No organizations.") }
62
+ end
63
+ end
64
+
65
+ context 'when there are organizations' do
66
+ let(:renamed_organization) { organizations.first }
67
+
68
+ context 'when the defaults are used' do
69
+ it 'asks for the organization and new name and renames' do
70
+ mock_ask("Rename which organization?", anything) { renamed_organization }
71
+ mock_ask("New name") { new_name }
72
+ mock(renamed_organization).name=(new_name)
73
+ mock(renamed_organization).update!
74
+ subject
75
+ end
76
+ end
77
+
78
+ context 'when no name is provided, but an organization is' do
79
+ let(:given) { { :organization => renamed_organization.name } }
80
+
81
+ it 'asks for the new name and renames' do
82
+ dont_allow_ask("Rename which organization?", anything)
83
+ mock_ask("New name") { new_name }
84
+ mock(renamed_organization).name=(new_name)
85
+ mock(renamed_organization).update!
86
+ subject
87
+ end
88
+ end
89
+
90
+ context 'when an organization is provided and a name' do
91
+ let(:inputs) { { :organization => renamed_organization, :name => new_name } }
92
+
93
+ it 'renames the organization' do
94
+ mock(renamed_organization).update!
95
+ subject
96
+ end
97
+
98
+ it 'displays the progress' do
99
+ mock_with_progress("Renaming to #{new_name}")
100
+ mock(renamed_organization).update!
101
+
102
+ subject
103
+ end
104
+
105
+ context 'and the name already exists' do
106
+ it 'fails' do
107
+ mock(renamed_organization).update! { raise CFoundry::OrganizationNameTaken.new("Bad error", 200) }
108
+ expect { subject }.to raise_error(CFoundry::OrganizationNameTaken)
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+
3
+ describe VMC::Route::Map do
4
+ let(:inputs) { {} }
5
+ let(:global) { { :color => false } }
6
+ let(:given) { {} }
7
+ let(:client) { fake_client }
8
+ let!(:cli) { described_class.new }
9
+
10
+ before do
11
+ stub(cli).client { client }
12
+ stub_output(cli)
13
+ end
14
+
15
+ let(:app){ fake(:app, :space => space, :name => "app-name") }
16
+ let(:space) { fake(:space, :name => "space-name", :domains => space_domains) }
17
+ let(:domain) { fake(:domain, :name => domain_name ) }
18
+ let(:domain_name) { "some-domain.com" }
19
+ let(:host_name) { "some-host" }
20
+ let(:space_domains) { [] }
21
+
22
+ subject { invoke_cli(cli, :map, inputs, given, global) }
23
+
24
+ context 'when targeting v2' do
25
+ shared_examples "mapping the route to the app" do
26
+ context 'and the domain is mapped to the space' do
27
+ let(:space_domains) { [domain] }
28
+
29
+ context 'and the route is mapped to the space' do
30
+ let(:client) { fake_client :routes => [route] }
31
+ let(:route) { fake(:route, :space => space, :host => host_name, :domain => domain) }
32
+
33
+ it 'binds the route to the app' do
34
+ mock(app).add_route(route)
35
+ subject
36
+ end
37
+ end
38
+
39
+ context 'and the route is not mapped to the space' do
40
+ let(:new_route) { fake(:route) }
41
+
42
+ before do
43
+ stub(client).route { new_route }
44
+ stub(app).add_route
45
+ stub(new_route).create!
46
+ end
47
+
48
+ it 'indicates that it is creating a route' do
49
+ mock(cli).print("Creating route #{host_name}.#{domain_name}")
50
+ subject
51
+ end
52
+
53
+ it "creates the route in the app's space" do
54
+ mock(new_route).create!
55
+ subject
56
+ expect(new_route.host).to eq host_name
57
+ expect(new_route.domain).to eq domain
58
+ expect(new_route.space).to eq space
59
+ end
60
+
61
+ it 'indicates that it is binding the route' do
62
+ mock(cli).print("Binding #{host_name}.#{domain_name} to app-name")
63
+ subject
64
+ end
65
+
66
+ it 'binds the route to the app' do
67
+ mock(app).add_route(new_route)
68
+ subject
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'when an app is specified' do
75
+ let(:inputs) { { :domain => domain, :host => host_name, :app => app } }
76
+
77
+ context 'and the domain is not already mapped to the space' do
78
+ let(:space_domains) { [] }
79
+ let(:inputs) { { :app => app } }
80
+ let(:given) { { :domain => "some-bad-domain" }}
81
+
82
+ it 'indicates that the domain is invalid' do
83
+ expect { subject }.to raise_error(VMC::UserError, /Unknown domain/)
84
+ end
85
+ end
86
+
87
+ include_examples "mapping the route to the app"
88
+ end
89
+
90
+ context 'when an app is not specified' do
91
+ let(:inputs) { { :domain => domain, :host => host_name } }
92
+ let(:space_domains) { [domain] }
93
+ let(:new_route) { fake(:route) }
94
+
95
+ before { stub_ask("Which application?", anything) { app } }
96
+
97
+ it 'asks for an app' do
98
+ stub(client).route { new_route }
99
+ stub(app).add_route
100
+ stub(new_route).create!
101
+ mock_ask("Which application?", anything) { app }
102
+ subject
103
+ end
104
+
105
+ include_examples "mapping the route to the app"
106
+ end
107
+
108
+ context "when a host is not specified" do
109
+ let(:inputs) { { :domain => domain, :app => app } }
110
+ let(:new_route) { fake(:route) }
111
+
112
+ before do
113
+ stub(client).route { new_route }
114
+ stub(app).add_route
115
+ stub(new_route).create!
116
+ end
117
+
118
+ it "creates a route with an empty string as its host" do
119
+ mock(new_route).create!
120
+ subject
121
+ expect(new_route.host).to eq ""
122
+ end
123
+ end
124
+ end
125
+
126
+ context 'when targeting v1' do
127
+ let(:given) { { :domain => "foo.bar.com" } }
128
+ let(:app) { v1_fake :app, :name => "foo" }
129
+ let(:client) { v1_fake_client }
130
+ let(:inputs) { { :app => app } }
131
+
132
+ it "adds the domain to the app's urls" do
133
+ stub(app).update!
134
+ subject
135
+ expect(app.urls).to include "foo.bar.com"
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,215 @@
1
+ require 'spec_helper'
2
+
3
+ describe VMC::Route::Unmap do
4
+ let(:global) { { :color => false } }
5
+ let(:given) { {} }
6
+ let(:inputs) { {} }
7
+ let(:client) { fake_client }
8
+ let!(:cli) { described_class.new }
9
+ let(:app){ fake(:app, :space => space, :name => "app-name") }
10
+ let(:space) { fake(:space, :name => "space-name", :domains => space_domains) }
11
+ let(:domain) { fake(:domain, :name => domain_name ) }
12
+ let(:domain_name) { "some-domain.com" }
13
+ let(:host_name) { "some-host" }
14
+ let(:url) { "#{host_name}.#{domain_name}" }
15
+ let(:space_domains) { [domain] }
16
+
17
+ before do
18
+ stub(cli).client { client }
19
+ stub_output(cli)
20
+ end
21
+
22
+ subject { invoke_cli(cli, :unmap, inputs, given, global) }
23
+
24
+ describe 'metadata' do
25
+ let(:command) { Mothership.commands[:delete_service] }
26
+
27
+ describe 'command' do
28
+ subject { command }
29
+ its(:description) { should eq "Delete a service" }
30
+ it { expect(Mothership::Help.group(:services, :manage)).to include(subject) }
31
+ end
32
+
33
+ include_examples 'inputs must have descriptions'
34
+
35
+ describe 'arguments' do
36
+ subject { command.arguments }
37
+ it 'has the correct argument order' do
38
+ should eq([{:type => :optional, :value => nil, :name => :service }])
39
+ end
40
+ end
41
+ end
42
+
43
+ context 'when targeting v2' do
44
+ context "when an app and a url are specified" do
45
+ let(:given) { { :url => url } }
46
+ let(:inputs) { { :app => app } }
47
+
48
+ context "when the given route is mapped to the given app" do
49
+ let(:client) { fake_client :routes => [route] }
50
+ let(:app) { fake(:app, :space => space, :name => "app-name", :routes => [route]) }
51
+ let(:route) { fake(:route, :space => space, :host => host_name, :domain => domain) }
52
+
53
+ it "unmaps the url from the app" do
54
+ mock(app).remove_route(route)
55
+ subject
56
+ end
57
+ end
58
+
59
+ context "when the given route is NOT mapped to the given app" do
60
+ it "displays an error" do
61
+ expect { subject }.to raise_error(VMC::UserError, /Unknown route/)
62
+ end
63
+ end
64
+ end
65
+
66
+ context "when only an app is specified" do
67
+ let(:other_route) { fake(:route, :host => "abcd", :domain => domain) }
68
+ let(:route) { fake(:route, :host => "efgh", :domain => domain) }
69
+ let(:app) { fake(:app, :space => space, :routes => [route, other_route] )}
70
+ let(:inputs) { { :app => app } }
71
+
72
+ before { stub(app).remove_route(route) }
73
+
74
+ it "asks the user to select from the app's urls" do
75
+ mock_ask("Which URL?", anything) do |_, opts|
76
+ expect(opts[:choices]).to eq [other_route, route]
77
+ route
78
+ end
79
+
80
+ subject
81
+ end
82
+
83
+ it "unmaps the selected url from the app" do
84
+ stub_ask("Which URL?", anything) { route }
85
+ mock(app).remove_route(route)
86
+ subject
87
+ end
88
+ end
89
+
90
+ context "when an app is specified and the --all option is given" do
91
+ let(:other_route) { fake(:route, :host => "abcd", :domain => domain) }
92
+ let(:route) { fake(:route, :host => "efgh", :domain => domain) }
93
+ let(:app) { fake(:app, :routes => [route, other_route]) }
94
+ let(:inputs) { { :app => app, :all => true } }
95
+
96
+ it "unmaps all routes from the given app" do
97
+ mock(app).remove_route(route)
98
+ mock(app).remove_route(other_route)
99
+ subject
100
+ end
101
+ end
102
+
103
+ context "when a url is specified and the --delete option is given" do
104
+ let(:route) { fake(:route, :host => host_name, :domain => domain) }
105
+ let(:client) { fake_client :routes => [route] }
106
+ let(:given) { { :url => url } }
107
+ let(:inputs) { { :delete => true } }
108
+
109
+ it "deletes the route" do
110
+ mock(route).delete!
111
+ subject
112
+ end
113
+ end
114
+
115
+ context "when the --delete and --all options are both passed" do
116
+ let(:inputs) { { :delete => true, :all => true } }
117
+ let(:other_route) { fake(:route, :host => "abcd", :domain => domain) }
118
+ let(:route) { fake(:route, :host => "efgh", :domain => domain) }
119
+ let(:client) { fake_client :routes => [route, other_route] }
120
+
121
+ it "asks if the user really wants to unmap all urls" do
122
+ mock_ask("Really delete ALL URLS?", :default => false) { false }
123
+ subject
124
+ end
125
+
126
+ context "when the user responds with a yes" do
127
+ before { stub_ask("Really delete ALL URLS?", anything) { true } }
128
+
129
+ it "deletes all the user's routes" do
130
+ client.routes.each { |r| mock(r).delete! }
131
+ subject
132
+ end
133
+ end
134
+
135
+ context "when the user responds with a no" do
136
+ before { stub_ask("Really delete ALL URLS?", anything) { false } }
137
+
138
+ it "does not delete any routes" do
139
+ any_instance_of(route.class) do |route|
140
+ dont_allow(route).delete!
141
+ end
142
+ subject
143
+ end
144
+ end
145
+ end
146
+
147
+ context "when only a url is passed" do
148
+ let(:route) { fake(:route, :host => host_name, :domain => domain) }
149
+ let(:client) { fake_client :routes => [route] }
150
+ let(:given) { { :url => url } }
151
+
152
+ it "displays an error message" do
153
+ expect { subject }.to raise_error(VMC::UserError, /Missing either --delete or --app/)
154
+ end
155
+ end
156
+ end
157
+
158
+ context 'when targeting v1' do
159
+ let(:client) { CFoundry::V1::Client.new }
160
+ let(:app) { CFoundry::V1::App.new("some-app", client) }
161
+ let(:other_url) { "some.other.url.com" }
162
+
163
+ context "when an app and a url are specified" do
164
+ let(:given) { { :url => url } }
165
+ let(:inputs) { { :app => app } }
166
+
167
+ context "when the given url is not mapped to the app" do
168
+ before { app.urls = [other_url] }
169
+
170
+ it "displays an error message" do
171
+ expect { subject }.to raise_error(VMC::UserError, /URL.*not mapped/)
172
+ end
173
+ end
174
+
175
+ context "when the given url is mapped to the app" do
176
+ before { app.urls = [url, other_url] }
177
+
178
+ it "unmaps the url from the app" do
179
+ mock(app).update!
180
+ subject
181
+ expect(app.urls).to eq [other_url]
182
+ end
183
+ end
184
+ end
185
+
186
+ context "when only an app is specified" do
187
+ let(:inputs) { { :app => app } }
188
+ before { app.urls = [url, other_url] }
189
+
190
+ it "asks for the url" do
191
+ mock_ask("Which URL?", :choices => [url, other_url]) { url }
192
+ stub(app).update!
193
+ subject
194
+ end
195
+
196
+ it "unmaps the selected url from the app" do
197
+ stub_ask("Which URL?", anything) { url }
198
+ mock(app).update!
199
+ subject
200
+ expect(app.urls).to eq [other_url]
201
+ end
202
+ end
203
+
204
+ context "when an app is specified and the --all option is given" do
205
+ let(:inputs) { { :app => app, :all => true } }
206
+
207
+ it "unmaps all routes from the given app" do
208
+ app.urls = ["foo", "bar"]
209
+ mock(app).update!
210
+ subject
211
+ expect(app.urls).to eq []
212
+ end
213
+ end
214
+ end
215
+ end