cfoundry 1.5.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/cfoundry/test_support.rb +2 -2
- data/lib/cfoundry/v2/app.rb +3 -6
- data/lib/cfoundry/v2/model.rb +1 -0
- data/lib/cfoundry/version.rb +1 -1
- data/spec/cfoundry/client_spec.rb +1 -1
- data/spec/cfoundry/rest_client_spec.rb +1 -1
- data/spec/cfoundry/trace_helpers_spec.rb +6 -6
- data/spec/cfoundry/upload_helpers_spec.rb +125 -137
- data/spec/cfoundry/v2/app_event_spec.rb +63 -59
- data/spec/cfoundry/v2/app_spec.rb +195 -188
- data/spec/cfoundry/v2/client_spec.rb +60 -56
- data/spec/cfoundry/v2/domain_spec.rb +9 -6
- data/spec/cfoundry/v2/model_magic/model_magic/attribute_spec.rb +89 -88
- data/spec/cfoundry/v2/model_magic/model_magic/has_summary_spec.rb +12 -13
- data/spec/cfoundry/v2/model_magic/model_magic/to_many_spec.rb +46 -52
- data/spec/cfoundry/v2/model_magic/model_magic/to_one_spec.rb +96 -87
- data/spec/cfoundry/v2/model_spec.rb +236 -241
- data/spec/cfoundry/v2/organization_spec.rb +20 -22
- data/spec/cfoundry/v2/quota_definition_spec.rb +45 -47
- data/spec/cfoundry/v2/route_spec.rb +28 -25
- data/spec/cfoundry/v2/space_spec.rb +9 -11
- data/spec/cfoundry/validator_spec.rb +69 -67
- data/spec/factories/app_events_factory.rb +7 -0
- data/spec/factories/apps_factory.rb +11 -0
- data/spec/factories/clients_factory.rb +5 -0
- data/spec/factories/domains_factory.rb +7 -0
- data/spec/factories/organizations_factory.rb +11 -0
- data/spec/factories/quota_definitions_factory.rb +8 -0
- data/spec/factories/routes_factory.rb +10 -0
- data/spec/factories/spaces_factory.rb +10 -0
- data/spec/factories/users_factory.rb +10 -0
- data/spec/spec_helper.rb +5 -4
- data/spec/support/factory_girl.rb +6 -0
- data/spec/support/shared_examples/model_summary_examples.rb +7 -7
- data/spec/support/test_model_builder.rb +10 -0
- metadata +83 -71
- data/spec/fakes/app_fake.rb +0 -5
- data/spec/fakes/domain_fake.rb +0 -5
- data/spec/fakes/framework_fake.rb +0 -5
- data/spec/fakes/organization_fake.rb +0 -5
- data/spec/fakes/route_fake.rb +0 -5
- data/spec/fakes/runtime_fake.rb +0 -5
- data/spec/fakes/service_fake.rb +0 -5
- data/spec/fakes/service_instance_fake.rb +0 -5
- data/spec/fakes/service_plan_fake.rb +0 -5
- data/spec/fakes/space_fake.rb +0 -5
- data/spec/fakes/user_fake.rb +0 -5
- data/spec/support/fake_helper.rb +0 -248
- data/spec/support/randoms.rb +0 -3
@@ -1,249 +1,256 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
module CFoundry
|
4
|
+
module V2
|
5
|
+
describe App do
|
6
|
+
let(:client) { build(:client) }
|
5
7
|
|
6
|
-
|
8
|
+
subject { build(:app, :client => client) }
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
+
describe "#events" do
|
11
|
+
let(:events) { [build(:app_event)] }
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
it "has events" do
|
14
|
+
subject.events = events
|
15
|
+
expect(subject.events).to eq(events)
|
16
|
+
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
context "when an invalid value is assigned" do
|
19
|
+
it "raises a Mismatch exception" do
|
20
|
+
expect {
|
21
|
+
subject.events = [build(:organization)]
|
22
|
+
}.to raise_error(CFoundry::Mismatch)
|
23
|
+
end
|
24
|
+
end
|
21
25
|
end
|
22
|
-
end
|
23
|
-
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
+
describe "environment" do
|
28
|
+
let(:app) { build(:app, :env => {"FOO" => "1"}) }
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
30
|
+
it "returns a hash-like object" do
|
31
|
+
expect(app.env["FOO"]).to eq "1"
|
32
|
+
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
+
describe "converting keys and values to strings" do
|
35
|
+
let(:app) { build(:app, :env => {:FOO => 1}) }
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
it "converts keys and values to strings" do
|
38
|
+
expect(app.env.to_hash).to eq("FOO" => "1")
|
39
|
+
end
|
40
|
+
end
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
context "when changes are made to the hash-like object" do
|
43
|
+
it "reflects the changes in .env" do
|
44
|
+
expect {
|
45
|
+
app.env["BAR"] = "2"
|
46
|
+
}.to change { app.env.to_hash }.from("FOO" => "1").to("FOO" => "1", "BAR" => "2")
|
47
|
+
end
|
48
|
+
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
context "when the env is set to something else" do
|
51
|
+
it "reflects the changes in .env" do
|
52
|
+
expect {
|
53
|
+
app.env = {"BAR" => "2"}
|
54
|
+
}.to change { app.env.to_hash }.from("FOO" => "1").to("BAR" => "2")
|
55
|
+
end
|
56
|
+
end
|
53
57
|
end
|
54
|
-
end
|
55
|
-
end
|
56
58
|
|
57
|
-
|
58
|
-
|
59
|
+
describe "#summarize!" do
|
60
|
+
let(:app) { build(:app) }
|
59
61
|
|
60
|
-
|
61
|
-
|
62
|
+
it "assigns :instances as #total_instances" do
|
63
|
+
stub(app).summary { {:instances => 4} }
|
62
64
|
|
63
|
-
|
65
|
+
app.summarize!
|
64
66
|
|
65
|
-
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
shared_examples_for "something may stage the app" do
|
70
|
-
subject { fake :app, :client => client }
|
71
|
-
let(:response) { { :body => '{ "foo": "bar" }' } }
|
72
|
-
|
73
|
-
before do
|
74
|
-
stub(client.base).put("v2", "apps", subject.guid, anything) do
|
75
|
-
response
|
67
|
+
expect(app.total_instances).to eq(4)
|
68
|
+
end
|
76
69
|
end
|
77
|
-
end
|
78
70
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
71
|
+
shared_examples_for "something may stage the app" do
|
72
|
+
subject { build(:app, :client => client) }
|
73
|
+
let(:response) { {:body => '{ "foo": "bar" }'} }
|
74
|
+
|
75
|
+
before do
|
76
|
+
stub(client.base).put("v2", "apps", subject.guid, anything) do
|
77
|
+
response
|
78
|
+
end
|
87
79
|
end
|
88
80
|
|
89
|
-
|
90
|
-
|
81
|
+
context "when asynchronous is true" do
|
82
|
+
it "sends the PUT request with &stage_async=true" do
|
83
|
+
mock(client.base).put(
|
84
|
+
"v2", "apps", subject.guid,
|
85
|
+
hash_including(
|
86
|
+
:params => {:stage_async => true},
|
87
|
+
:return_response => true)) do
|
88
|
+
response
|
89
|
+
end
|
90
|
+
|
91
|
+
update(true)
|
92
|
+
end
|
91
93
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
context "and a block is given" do
|
95
|
+
let(:response) do
|
96
|
+
{:headers => {"x-app-staging-log" => "http://app/staging/log"},
|
97
|
+
:body => "{}"
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
it "yields the URL for the logs" do
|
102
|
+
yielded_url = nil
|
103
|
+
update(true) do |url|
|
104
|
+
yielded_url = url
|
105
|
+
end
|
106
|
+
|
107
|
+
expect(yielded_url).to eq "http://app/staging/log"
|
108
|
+
end
|
109
|
+
end
|
97
110
|
end
|
98
111
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
112
|
+
context "when asynchronous is false" do
|
113
|
+
it "sends the PUT request with &stage_async=false" do
|
114
|
+
mock(client.base).put(
|
115
|
+
"v2", "apps", subject.guid,
|
116
|
+
hash_including(:params => {:stage_async => false})) do
|
117
|
+
response
|
118
|
+
end
|
104
119
|
|
105
|
-
|
120
|
+
update(false)
|
121
|
+
end
|
106
122
|
end
|
107
123
|
end
|
108
|
-
end
|
109
124
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
response
|
125
|
+
describe "#start!" do
|
126
|
+
it_should_behave_like "something may stage the app" do
|
127
|
+
def update(async, &blk)
|
128
|
+
subject.start!(async, &blk)
|
129
|
+
end
|
116
130
|
end
|
117
|
-
|
118
|
-
update(false)
|
119
131
|
end
|
120
|
-
end
|
121
|
-
end
|
122
132
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
133
|
+
describe "#restart!" do
|
134
|
+
it_should_behave_like "something may stage the app" do
|
135
|
+
def update(async, &blk)
|
136
|
+
subject.restart!(async, &blk)
|
137
|
+
end
|
138
|
+
end
|
127
139
|
end
|
128
|
-
end
|
129
|
-
end
|
130
140
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
141
|
+
describe "#update!" do
|
142
|
+
describe "changes" do
|
143
|
+
subject { build(:app, :client => client) }
|
144
|
+
let(:response) { {:body => { "foo" => "bar" }.to_json } }
|
138
145
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
146
|
+
before do
|
147
|
+
stub(client.base).put("v2", "apps", subject.guid, anything) do
|
148
|
+
response
|
149
|
+
end
|
150
|
+
end
|
143
151
|
|
144
|
-
|
145
|
-
|
146
|
-
|
152
|
+
it "applies the changes from the response JSON" do
|
153
|
+
expect {
|
154
|
+
subject.update!
|
155
|
+
}.to change { subject.manifest }.to(:foo => "bar")
|
156
|
+
end
|
147
157
|
end
|
148
|
-
end
|
149
|
-
|
150
|
-
it "applies the changes from the response JSON" do
|
151
|
-
expect {
|
152
|
-
subject.update!
|
153
|
-
}.to change { subject.manifest }.to(:foo => "bar")
|
154
|
-
end
|
155
|
-
end
|
156
158
|
|
157
|
-
|
158
|
-
|
159
|
-
|
159
|
+
it_should_behave_like "something may stage the app" do
|
160
|
+
def update(async, &blk)
|
161
|
+
subject.update!(async, &blk)
|
162
|
+
end
|
163
|
+
end
|
160
164
|
end
|
161
|
-
end
|
162
|
-
end
|
163
165
|
|
164
|
-
|
165
|
-
|
166
|
-
let(:base_url) { "http://example.com/log" }
|
166
|
+
describe "#stream_update_log" do
|
167
|
+
let(:base_url) { "http://example.com/log" }
|
167
168
|
|
168
|
-
|
169
|
+
def mock_log(url = anything)
|
170
|
+
mock(client).stream_url(url) do |_, blk|
|
171
|
+
blk.call(yield)
|
172
|
+
end.ordered
|
173
|
+
end
|
169
174
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
+
def stub_log(url = anything)
|
176
|
+
stub(client).stream_url(url) do |_, blk|
|
177
|
+
blk.call(yield)
|
178
|
+
end.ordered
|
179
|
+
end
|
175
180
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
end
|
181
|
+
it "yields chunks from the response to the block" do
|
182
|
+
mock_log { "a" }
|
183
|
+
mock_log { "b" }
|
184
|
+
mock_log { raise CFoundry::NotFound }
|
181
185
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
+
chunks = []
|
187
|
+
subject.stream_update_log(base_url) do |chunk|
|
188
|
+
chunks << chunk
|
189
|
+
end
|
186
190
|
|
187
|
-
|
188
|
-
|
189
|
-
chunks << chunk
|
190
|
-
end
|
191
|
+
expect(chunks).to eq(%w(a b))
|
192
|
+
end
|
191
193
|
|
192
|
-
|
193
|
-
|
194
|
+
it "retries when the connection times out" do
|
195
|
+
mock_log { raise ::Timeout::Error }
|
196
|
+
mock_log { "a" }
|
197
|
+
mock_log { raise ::Timeout::Error }
|
198
|
+
mock_log { "b" }
|
199
|
+
mock_log { raise ::Timeout::Error }
|
200
|
+
mock_log { raise CFoundry::NotFound }
|
201
|
+
|
202
|
+
chunks = []
|
203
|
+
subject.stream_update_log(base_url) do |chunk|
|
204
|
+
chunks << chunk
|
205
|
+
end
|
194
206
|
|
195
|
-
|
196
|
-
|
197
|
-
mock_log { "a" }
|
198
|
-
mock_log { raise Timeout::Error }
|
199
|
-
mock_log { "b" }
|
200
|
-
mock_log { raise Timeout::Error }
|
201
|
-
mock_log { raise CFoundry::NotFound }
|
202
|
-
|
203
|
-
chunks = []
|
204
|
-
subject.stream_update_log(base_url) do |chunk|
|
205
|
-
chunks << chunk
|
206
|
-
end
|
207
|
+
expect(chunks).to eq(%w(a b))
|
208
|
+
end
|
207
209
|
|
208
|
-
|
209
|
-
|
210
|
+
it "tracks the offset to stream from" do
|
211
|
+
url = "#{base_url}&tail&tail_offset="
|
210
212
|
|
211
|
-
|
212
|
-
|
213
|
+
mock_log("#{url}0") { "a" }
|
214
|
+
mock_log("#{url}1") { raise ::Timeout::Error }
|
215
|
+
mock_log("#{url}1") { "b" }
|
216
|
+
mock_log("#{url}2") { raise CFoundry::NotFound }
|
213
217
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
+
chunks = []
|
219
|
+
subject.stream_update_log(base_url) do |chunk|
|
220
|
+
chunks << chunk
|
221
|
+
end
|
218
222
|
|
219
|
-
|
220
|
-
|
221
|
-
chunks << chunk
|
222
|
-
end
|
223
|
+
expect(chunks).to eq(%w(a b))
|
224
|
+
end
|
223
225
|
|
224
|
-
|
225
|
-
|
226
|
+
it "stops when the endpoint disappears" do
|
227
|
+
mock_log { "a" }
|
228
|
+
mock_log { "b" }
|
229
|
+
mock_log { raise CFoundry::NotFound }
|
230
|
+
stub_log { "c" }
|
226
231
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
stub_log { "c" }
|
232
|
+
chunks = []
|
233
|
+
subject.stream_update_log(base_url) do |chunk|
|
234
|
+
chunks << chunk
|
235
|
+
end
|
232
236
|
|
233
|
-
|
234
|
-
|
235
|
-
chunks << chunk
|
237
|
+
expect(chunks).to eq(%w(a b))
|
238
|
+
end
|
236
239
|
end
|
237
240
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
+
describe "delete!" do
|
242
|
+
it "defaults to recursive" do
|
243
|
+
mock(client.base).delete("v2", :apps, subject.guid, {:params => {:recursive => true}})
|
241
244
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
+
subject.delete!
|
246
|
+
end
|
247
|
+
end
|
245
248
|
|
246
|
-
|
249
|
+
it "accepts and ignores an options hash" do
|
250
|
+
mock(client.base).delete("v2", :apps, subject.guid, {:params => {:recursive => true}})
|
251
|
+
|
252
|
+
subject.delete!(:recursive => false)
|
253
|
+
end
|
247
254
|
end
|
248
255
|
end
|
249
256
|
end
|
@@ -1,73 +1,77 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
module CFoundry
|
4
|
+
module V2
|
5
|
+
describe Client do
|
6
|
+
let(:client) { build(:client) }
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
describe "#register" do
|
9
|
+
let(:uaa) { UAAClient.new }
|
10
|
+
let(:email) { "test@test.com" }
|
11
|
+
let(:password) { "secret" }
|
10
12
|
|
11
|
-
|
13
|
+
subject { client.register(email, password) }
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
it "creates the user in uaa and ccng" do
|
16
|
+
stub(client.base).uaa { uaa }
|
17
|
+
stub(uaa).add_user(email, password) { {"id" => "1234"} }
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
user = build(:user)
|
20
|
+
stub(client).user { user }
|
21
|
+
stub(user).create!
|
22
|
+
subject
|
23
|
+
expect(user.guid).to eq "1234"
|
24
|
+
end
|
25
|
+
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
describe "#current_user" do
|
28
|
+
subject { client.current_user }
|
29
|
+
before { client.token = token }
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
context "when there is no token" do
|
32
|
+
let(:token) { nil }
|
33
|
+
it { should eq nil }
|
34
|
+
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
context "when there is access_token_data" do
|
40
|
-
let(:token_data) { { :user_id => "123", :email => "guy@example.com" } }
|
41
|
-
let(:auth_header) { Base64.encode64("{}#{MultiJson.encode(token_data)}") }
|
42
|
-
let(:token) do
|
43
|
-
CFoundry::AuthToken.new("bearer #{auth_header}", "some-refresh-token")
|
44
|
-
end
|
36
|
+
context "when there is no access_token_data" do
|
37
|
+
let(:token) { AuthToken.new("bearer some-access-token", "some-refresh-token") }
|
38
|
+
it { should eq nil }
|
39
|
+
end
|
45
40
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
41
|
+
context "when there is access_token_data" do
|
42
|
+
let(:token_data) { {:user_id => "123", :email => "guy@example.com"} }
|
43
|
+
let(:auth_header) { Base64.encode64("{}#{MultiJson.encode(token_data)}") }
|
44
|
+
let(:token) do
|
45
|
+
CFoundry::AuthToken.new("bearer #{auth_header}", "some-refresh-token")
|
46
|
+
end
|
51
47
|
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
it { should be_a User }
|
49
|
+
its(:guid) { should eq "123" }
|
50
|
+
its(:emails) { should eq [{:value => "guy@example.com"}] }
|
51
|
+
end
|
52
|
+
end
|
55
53
|
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
describe "#version" do
|
55
|
+
its(:version) { should eq 2 }
|
56
|
+
end
|
59
57
|
|
60
|
-
|
61
|
-
|
62
|
-
it 'sets the current organization to nil' do
|
63
|
-
client.current_organization = "org"
|
64
|
-
expect { subject }.to change { client.current_organization }.from("org").to(nil)
|
58
|
+
describe "#login_prompts" do
|
59
|
+
include_examples "client login prompts"
|
65
60
|
end
|
66
61
|
|
67
|
-
|
68
|
-
client
|
69
|
-
|
62
|
+
describe "#login" do
|
63
|
+
include_examples "client login" do
|
64
|
+
it 'sets the current organization to nil' do
|
65
|
+
client.current_organization = "org"
|
66
|
+
expect { subject }.to change { client.current_organization }.from("org").to(nil)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'sets the current space to nil' do
|
70
|
+
client.current_space = "space"
|
71
|
+
expect { subject }.to change { client.current_space }.from("space").to(nil)
|
72
|
+
end
|
73
|
+
end
|
70
74
|
end
|
71
75
|
end
|
72
76
|
end
|
73
|
-
end
|
77
|
+
end
|