ncfoundry 4.9.2
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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.gitmodules +3 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +11 -0
- data/Checkfile +2 -0
- data/Gemfile +3 -0
- data/LICENSE +987 -0
- data/NOTICE +10 -0
- data/README.md +9 -0
- data/Rakefile +14 -0
- data/VERSION +1 -0
- data/cfoundry.gemspec +41 -0
- data/config/locales/en.yml +168 -0
- data/lib/cc_api_stub/app_usage_events.rb +11 -0
- data/lib/cc_api_stub/applications.rb +57 -0
- data/lib/cc_api_stub/domains.rb +32 -0
- data/lib/cc_api_stub/events.rb +11 -0
- data/lib/cc_api_stub/frameworks.rb +22 -0
- data/lib/cc_api_stub/helper.rb +148 -0
- data/lib/cc_api_stub/login.rb +21 -0
- data/lib/cc_api_stub/organization_users.rb +27 -0
- data/lib/cc_api_stub/organizations.rb +82 -0
- data/lib/cc_api_stub/routes.rb +26 -0
- data/lib/cc_api_stub/runtimes.rb +22 -0
- data/lib/cc_api_stub/service_bindings.rb +22 -0
- data/lib/cc_api_stub/service_instances.rb +22 -0
- data/lib/cc_api_stub/services.rb +21 -0
- data/lib/cc_api_stub/space_users.rb +27 -0
- data/lib/cc_api_stub/spaces.rb +58 -0
- data/lib/cc_api_stub/users.rb +85 -0
- data/lib/cc_api_stub.rb +20 -0
- data/lib/cfoundry/auth_token.rb +62 -0
- data/lib/cfoundry/baseclient.rb +220 -0
- data/lib/cfoundry/chatty_hash.rb +46 -0
- data/lib/cfoundry/client.rb +42 -0
- data/lib/cfoundry/concerns/login_helpers.rb +14 -0
- data/lib/cfoundry/concerns/proxy_options.rb +14 -0
- data/lib/cfoundry/errors.rb +163 -0
- data/lib/cfoundry/rest_client.rb +316 -0
- data/lib/cfoundry/test_support.rb +3 -0
- data/lib/cfoundry/trace_helpers.rb +64 -0
- data/lib/cfoundry/uaaclient.rb +151 -0
- data/lib/cfoundry/upload_helpers.rb +222 -0
- data/lib/cfoundry/v2/app.rb +313 -0
- data/lib/cfoundry/v2/app_event.rb +13 -0
- data/lib/cfoundry/v2/app_instance.rb +74 -0
- data/lib/cfoundry/v2/app_usage_event.rb +14 -0
- data/lib/cfoundry/v2/base.rb +112 -0
- data/lib/cfoundry/v2/client.rb +104 -0
- data/lib/cfoundry/v2/domain.rb +20 -0
- data/lib/cfoundry/v2/event.rb +17 -0
- data/lib/cfoundry/v2/helper.rb +11 -0
- data/lib/cfoundry/v2/managed_service_instance.rb +13 -0
- data/lib/cfoundry/v2/model.rb +213 -0
- data/lib/cfoundry/v2/model_magic/attribute.rb +49 -0
- data/lib/cfoundry/v2/model_magic/client_extensions.rb +170 -0
- data/lib/cfoundry/v2/model_magic/has_summary.rb +49 -0
- data/lib/cfoundry/v2/model_magic/query_multi_value_helper.rb +21 -0
- data/lib/cfoundry/v2/model_magic/query_value_helper.rb +33 -0
- data/lib/cfoundry/v2/model_magic/queryable_by.rb +39 -0
- data/lib/cfoundry/v2/model_magic/to_many.rb +145 -0
- data/lib/cfoundry/v2/model_magic/to_one.rb +81 -0
- data/lib/cfoundry/v2/model_magic.rb +134 -0
- data/lib/cfoundry/v2/organization.rb +44 -0
- data/lib/cfoundry/v2/quota_definition.rb +12 -0
- data/lib/cfoundry/v2/route.rb +25 -0
- data/lib/cfoundry/v2/service.rb +22 -0
- data/lib/cfoundry/v2/service_auth_token.rb +9 -0
- data/lib/cfoundry/v2/service_binding.rb +10 -0
- data/lib/cfoundry/v2/service_broker.rb +12 -0
- data/lib/cfoundry/v2/service_instance.rb +14 -0
- data/lib/cfoundry/v2/service_plan.rb +16 -0
- data/lib/cfoundry/v2/space.rb +31 -0
- data/lib/cfoundry/v2/stack.rb +10 -0
- data/lib/cfoundry/v2/user.rb +97 -0
- data/lib/cfoundry/v2/user_provided_service_instance.rb +16 -0
- data/lib/cfoundry/validator.rb +41 -0
- data/lib/cfoundry/version.rb +4 -0
- data/lib/cfoundry/zip.rb +56 -0
- data/lib/cfoundry.rb +6 -0
- data/release_notes/release_1_5_3.md +177 -0
- data/release_notes/release_2.3.1.md +14 -0
- data/release_notes/release_2.3.3.md +38 -0
- data/release_notes/release_2.3.4.md +16 -0
- data/release_notes/release_2.3.5.md +14 -0
- data/release_notes/release_2.3.6.md +14 -0
- data/release_notes/release_2.3.6.rc1.md +29 -0
- data/release_notes/release_2.3.6.rc2.md +19 -0
- data/release_notes/release_2.3.7.rc1.md +14 -0
- data/release_notes/release_2.4.0.md +41 -0
- data/release_notes/release_2.4.1.rc1.md +58 -0
- data/release_notes/release_3.0.0.md +21 -0
- data/release_notes/release_3.0.1.md +16 -0
- data/release_notes/release_3.0.2.rc1.md +19 -0
- data/release_notes/release_4.0.0.md +19 -0
- data/release_notes/release_4.0.1.md +14 -0
- data/release_notes/release_4.0.2.rc1.md +14 -0
- data/release_notes/release_4.0.2.rc2.md +11 -0
- data/release_notes/release_4.0.2.rc3.md +11 -0
- data/release_notes/release_4.0.2.rc4.md +19 -0
- data/release_notes/release_4.0.2.rc5.md +14 -0
- data/release_notes/release_4.0.3.md +19 -0
- data/release_notes/release_4.0.4.rc1.md +14 -0
- data/release_notes/release_4.0.4.rc2.md +14 -0
- data/release_notes/release_4.1.0.md +19 -0
- data/release_notes/release_4.2.0.rc.md +24 -0
- data/release_notes/release_4.3.0.md +22 -0
- data/release_notes/release_4.3.1.md +14 -0
- data/release_notes/release_4.3.10.md +14 -0
- data/release_notes/release_4.3.11.md +14 -0
- data/release_notes/release_4.3.12.md +14 -0
- data/release_notes/release_4.3.2.rc1.md +21 -0
- data/release_notes/release_4.3.3.md +24 -0
- data/release_notes/release_4.3.4.md +11 -0
- data/release_notes/release_4.3.4.rc1.md +24 -0
- data/release_notes/release_4.3.5.md +36 -0
- data/release_notes/release_4.3.5.rc1.md +21 -0
- data/release_notes/release_4.3.6.md +14 -0
- data/release_notes/release_4.3.7.md +50 -0
- data/release_notes/release_4.3.8.md +19 -0
- data/release_notes/release_4.3.9.md +14 -0
- data/release_notes/release_4.4.0.md +16 -0
- data/release_notes/release_4.5.1.md +11 -0
- data/release_notes/release_4.5.2.md +14 -0
- data/release_notes/release_4.5.3.md +29 -0
- data/release_notes/release_4.6.0.md +24 -0
- data/release_notes/release_4.6.1.md +14 -0
- data/release_notes/release_4.6.2.md +16 -0
- data/release_notes/release_4.6.3.rc1.md +14 -0
- data/release_notes/release_4.6.3.rc2.md +14 -0
- data/release_notes/release_4.6.3.rc3.md +17 -0
- data/release_notes/release_4.7.0.md +11 -0
- data/release_notes/release_4.7.1.md +14 -0
- data/release_notes/release_4.7.1.rc.1.md +14 -0
- data/release_notes/release_4.7.1.rc1.md +19 -0
- data/script/gpp +3 -0
- data/spec/cc_api_stub/app_usage_events_spec.rb +12 -0
- data/spec/cc_api_stub/applications_spec.rb +69 -0
- data/spec/cc_api_stub/domains_spec.rb +40 -0
- data/spec/cc_api_stub/events_spec.rb +12 -0
- data/spec/cc_api_stub/frameworks_spec.rb +19 -0
- data/spec/cc_api_stub/login_spec.rb +20 -0
- data/spec/cc_api_stub/organization_users_spec.rb +35 -0
- data/spec/cc_api_stub/organizations_spec.rb +118 -0
- data/spec/cc_api_stub/routes_spec.rb +19 -0
- data/spec/cc_api_stub/runtimes_spec.rb +19 -0
- data/spec/cc_api_stub/service_bindings_spec.rb +13 -0
- data/spec/cc_api_stub/service_instances_spec.rb +19 -0
- data/spec/cc_api_stub/services_spec.rb +11 -0
- data/spec/cc_api_stub/space_users_spec.rb +35 -0
- data/spec/cc_api_stub/spaces_spec.rb +38 -0
- data/spec/cc_api_stub/users_spec.rb +107 -0
- data/spec/cfoundry/auth_token_spec.rb +153 -0
- data/spec/cfoundry/baseclient_spec.rb +284 -0
- data/spec/cfoundry/client_spec.rb +13 -0
- data/spec/cfoundry/errors_spec.rb +117 -0
- data/spec/cfoundry/rest_client_spec.rb +367 -0
- data/spec/cfoundry/trace_helpers_spec.rb +91 -0
- data/spec/cfoundry/uaaclient_spec.rb +421 -0
- data/spec/cfoundry/upload_helpers_spec.rb +182 -0
- data/spec/cfoundry/v2/app_event_spec.rb +97 -0
- data/spec/cfoundry/v2/app_instance_spec.rb +31 -0
- data/spec/cfoundry/v2/app_spec.rb +354 -0
- data/spec/cfoundry/v2/app_usage_event_spec.rb +15 -0
- data/spec/cfoundry/v2/base_spec.rb +375 -0
- data/spec/cfoundry/v2/client_spec.rb +121 -0
- data/spec/cfoundry/v2/domain_spec.rb +63 -0
- data/spec/cfoundry/v2/event_spec.rb +15 -0
- data/spec/cfoundry/v2/managed_service_instance_spec.rb +149 -0
- data/spec/cfoundry/v2/model_magic/attribute_spec.rb +123 -0
- data/spec/cfoundry/v2/model_magic/has_summary_spec.rb +17 -0
- data/spec/cfoundry/v2/model_magic/to_many_spec.rb +53 -0
- data/spec/cfoundry/v2/model_magic/to_one_spec.rb +106 -0
- data/spec/cfoundry/v2/model_magic_spec.rb +43 -0
- data/spec/cfoundry/v2/model_spec.rb +472 -0
- data/spec/cfoundry/v2/organization_spec.rb +282 -0
- data/spec/cfoundry/v2/quota_definition_spec.rb +50 -0
- data/spec/cfoundry/v2/route_spec.rb +42 -0
- data/spec/cfoundry/v2/service_plan_spec.rb +53 -0
- data/spec/cfoundry/v2/service_spec.rb +58 -0
- data/spec/cfoundry/v2/space_spec.rb +160 -0
- data/spec/cfoundry/v2/user_provided_service_instance_spec.rb +57 -0
- data/spec/cfoundry/v2/user_spec.rb +206 -0
- data/spec/cfoundry/validator_spec.rb +94 -0
- data/spec/factories/app_events_factory.rb +7 -0
- data/spec/factories/app_usage_events_factory.rb +32 -0
- data/spec/factories/apps_factory.rb +11 -0
- data/spec/factories/clients_factory.rb +7 -0
- data/spec/factories/domains_factory.rb +10 -0
- data/spec/factories/events_factory.rb +50 -0
- data/spec/factories/organizations_factory.rb +12 -0
- data/spec/factories/quota_definitions_factory.rb +8 -0
- data/spec/factories/routes_factory.rb +10 -0
- data/spec/factories/service_instances_factory.rb +10 -0
- data/spec/factories/service_plans_factory.rb +10 -0
- data/spec/factories/services_factory.rb +10 -0
- data/spec/factories/spaces_factory.rb +10 -0
- data/spec/factories/user_provided_service_instances_factory.rb +10 -0
- data/spec/factories/users_factory.rb +10 -0
- data/spec/fixtures/apps/with_cfignore/.cfignore +4 -0
- data/spec/fixtures/apps/with_cfignore/.hidden_file +1 -0
- data/spec/fixtures/apps/with_cfignore/ambiguous_ignored +0 -0
- data/spec/fixtures/apps/with_cfignore/ignored_dir/file_in_ignored_dir.txt +1 -0
- data/spec/fixtures/apps/with_cfignore/ignored_file.txt +1 -0
- data/spec/fixtures/apps/with_cfignore/non_ignored_dir/file_in_non_ignored_dir.txt +1 -0
- data/spec/fixtures/apps/with_cfignore/non_ignored_dir/ignored_file.txt +1 -0
- data/spec/fixtures/apps/with_cfignore/non_ignored_dir/toplevel_ignored.txt +0 -0
- data/spec/fixtures/apps/with_cfignore/non_ignored_file.txt +1 -0
- data/spec/fixtures/apps/with_cfignore/toplevel_ignored.txt +0 -0
- data/spec/fixtures/apps/with_dotfiles/.dotfile +1 -0
- data/spec/fixtures/apps/with_dotfiles/xyz +1 -0
- data/spec/fixtures/apps/with_external_symlink/foo +1 -0
- data/spec/fixtures/apps/with_ignored_external_symlink/.cfignore +1 -0
- data/spec/fixtures/apps/with_ignored_external_symlink/foo +1 -0
- data/spec/fixtures/apps/with_nested_directories/foo/bar/baz/fizz +0 -0
- data/spec/fixtures/apps/with_nested_directories/xyz +0 -0
- data/spec/fixtures/empty_file +0 -0
- data/spec/fixtures/fake_cc_app_usage_events.json +152 -0
- data/spec/fixtures/fake_cc_application.json +20 -0
- data/spec/fixtures/fake_cc_application_summary.json +56 -0
- data/spec/fixtures/fake_cc_created_application.json +11 -0
- data/spec/fixtures/fake_cc_created_domain.json +15 -0
- data/spec/fixtures/fake_cc_created_organization.json +11 -0
- data/spec/fixtures/fake_cc_created_route.json +13 -0
- data/spec/fixtures/fake_cc_created_service_instance.json +11 -0
- data/spec/fixtures/fake_cc_created_space.json +11 -0
- data/spec/fixtures/fake_cc_created_user.json +11 -0
- data/spec/fixtures/fake_cc_domain.json +55 -0
- data/spec/fixtures/fake_cc_domain_spaces.json +27 -0
- data/spec/fixtures/fake_cc_empty_search.json +7 -0
- data/spec/fixtures/fake_cc_events.json +419 -0
- data/spec/fixtures/fake_cc_frameworks.json +20 -0
- data/spec/fixtures/fake_cc_managed_service_instance.json +83 -0
- data/spec/fixtures/fake_cc_organization.json +161 -0
- data/spec/fixtures/fake_cc_organization_domains.json +59 -0
- data/spec/fixtures/fake_cc_organization_search.json +37 -0
- data/spec/fixtures/fake_cc_organization_spaces.json +99 -0
- data/spec/fixtures/fake_cc_organization_summary.json +20 -0
- data/spec/fixtures/fake_cc_organization_users.json +81 -0
- data/spec/fixtures/fake_cc_route.json +16 -0
- data/spec/fixtures/fake_cc_runtimes.json +20 -0
- data/spec/fixtures/fake_cc_service_binding.json +22 -0
- data/spec/fixtures/fake_cc_service_bindings.json +24 -0
- data/spec/fixtures/fake_cc_service_instance.json +83 -0
- data/spec/fixtures/fake_cc_service_instances.json +72 -0
- data/spec/fixtures/fake_cc_services.json +160 -0
- data/spec/fixtures/fake_cc_space.json +45 -0
- data/spec/fixtures/fake_cc_space_apps.json +49 -0
- data/spec/fixtures/fake_cc_space_summary.json +84 -0
- data/spec/fixtures/fake_cc_spaces.json +92 -0
- data/spec/fixtures/fake_cc_stats.json +29 -0
- data/spec/fixtures/fake_cc_user.json +139 -0
- data/spec/fixtures/fake_cc_user_organizations.json +92 -0
- data/spec/fixtures/fake_cc_user_provided_service_instance.json +51 -0
- data/spec/fixtures/fake_cc_user_with_managers.json +85 -0
- data/spec/integration/client_spec.rb +38 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/factory_girl.rb +6 -0
- data/spec/support/shared_examples/cc_api_stub_request_examples.rb +79 -0
- data/spec/support/shared_examples/client_login_examples.rb +46 -0
- data/spec/support/shared_examples/model_summary_examples.rb +34 -0
- data/spec/support/test_model_builder.rb +10 -0
- data/vendor/errors/v1.yml +189 -0
- data/vendor/errors/v2.yml +845 -0
- metadata +712 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe CFoundry::V2::Base do
|
|
4
|
+
let(:target) { "https://api.example.com" }
|
|
5
|
+
let(:base) { CFoundry::V2::Base.new(target) }
|
|
6
|
+
|
|
7
|
+
describe "helper methods for HTTP verbs" do
|
|
8
|
+
let(:rest_client) { base.rest_client }
|
|
9
|
+
let(:path) { "some-path" }
|
|
10
|
+
let(:options) { { :some => :option} }
|
|
11
|
+
let(:url) { target + "/" + path }
|
|
12
|
+
let(:args) { [path, options] }
|
|
13
|
+
|
|
14
|
+
shared_examples "handling responses" do |verb|
|
|
15
|
+
context 'when successful' do
|
|
16
|
+
context 'and the accept type is JSON' do
|
|
17
|
+
let(:options) { {:accept => :json} }
|
|
18
|
+
|
|
19
|
+
it 'returns the parsed JSON' do
|
|
20
|
+
stub_request(:any, 'https://api.example.com/some-path').to_return(:status => 200, :body => "{\"hello\": \"there\"}")
|
|
21
|
+
expect(subject).to eq(:hello => "there")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context 'and the accept type is not JSON' do
|
|
26
|
+
let(:options) { {:accept => :form} }
|
|
27
|
+
|
|
28
|
+
it 'returns the body' do
|
|
29
|
+
stub_request(:any, 'https://api.example.com/some-path').to_return :status => 200, :body => "body"
|
|
30
|
+
expect(subject).to eq "body"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'when an error occurs' do
|
|
36
|
+
let(:response_code) { 404 }
|
|
37
|
+
|
|
38
|
+
it 'raises the correct error if JSON is parsed successfully' do
|
|
39
|
+
stub_request(:any, 'https://api.example.com/some-path').to_return(
|
|
40
|
+
:status => response_code,
|
|
41
|
+
:body => "{\"code\": 111, \"description\": \"Something bad happened\"}"
|
|
42
|
+
)
|
|
43
|
+
expect {subject}.to raise_error(CFoundry::SystemError, "111: Something bad happened")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'raises the correct error if code is missing from response' do
|
|
47
|
+
stub_request(:any, 'https://api.example.com/some-path').to_return(
|
|
48
|
+
:status => response_code,
|
|
49
|
+
:body => "{\"description\": \"Something bad happened\"}"
|
|
50
|
+
)
|
|
51
|
+
expect {subject}.to raise_error CFoundry::NotFound
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'raises the correct error if response body is not JSON' do
|
|
55
|
+
stub_request(:any, 'https://api.example.com/some-path').to_return(
|
|
56
|
+
:status => response_code,
|
|
57
|
+
:body => "Error happened"
|
|
58
|
+
)
|
|
59
|
+
expect {subject}.to raise_error CFoundry::NotFound
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'raises a generic APIError if code is not recognized' do
|
|
63
|
+
stub_request(:any, 'https://api.example.com/some-path').to_return :status => response_code,
|
|
64
|
+
:body => "{\"code\": 6932, \"description\": \"Something bad happened\"}"
|
|
65
|
+
expect {subject}.to raise_error CFoundry::APIError, "6932: Something bad happened"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context 'when a timeout exception occurs' do
|
|
69
|
+
before { stub_request(:any, url).to_raise(::Timeout::Error) }
|
|
70
|
+
|
|
71
|
+
it 'raises the correct error' do
|
|
72
|
+
expect { subject }.to raise_error CFoundry::Timeout, /#{url} timed out/
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'when an HTTPNotFound error occurs' do
|
|
77
|
+
before { stub_request(:any, url).to_return(:status => 404, :body => "NOT FOUND") }
|
|
78
|
+
|
|
79
|
+
it 'raises the correct error' do
|
|
80
|
+
expect {subject}.to raise_error CFoundry::NotFound, "404: NOT FOUND"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context 'when an HTTPForbidden error occurs' do
|
|
85
|
+
before { stub_request(:any, url).to_return(:status => 403, :body => "NONE SHALL PASS") }
|
|
86
|
+
|
|
87
|
+
it 'raises the correct error' do
|
|
88
|
+
expect { subject }.to raise_error CFoundry::Denied, "403: NONE SHALL PASS"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
context 'when an HTTPUnauthorized error occurs' do
|
|
93
|
+
before { stub_request(:any, url).to_return(:status => 401, :body => "YE FOO SHALL BAR") }
|
|
94
|
+
|
|
95
|
+
it 'raises the correct error' do
|
|
96
|
+
expect { subject }.to raise_error CFoundry::Unauthorized, "401: YE FOO SHALL BAR"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context "when any other type of error occurs" do
|
|
101
|
+
before { stub_request(:any, url).to_return(:status => 411, :body => "NOT LONG ENOUGH") }
|
|
102
|
+
|
|
103
|
+
it 'raises the correct error' do
|
|
104
|
+
expect { subject }.to raise_error CFoundry::BadResponse, "411: NOT LONG ENOUGH"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'includes the request and response hashes when it raises errors' do
|
|
109
|
+
stub_request(:any, url).to_return(:status => 411, :body => "NOT LONG ENOUGH")
|
|
110
|
+
|
|
111
|
+
begin
|
|
112
|
+
subject
|
|
113
|
+
rescue CFoundry::BadResponse => e
|
|
114
|
+
expect(e.response).to eq({
|
|
115
|
+
:status => "411",
|
|
116
|
+
:headers => {},
|
|
117
|
+
:body => "NOT LONG ENOUGH"
|
|
118
|
+
})
|
|
119
|
+
expect(e.request).to eq({
|
|
120
|
+
:headers => { "Content-Length" => 0 },
|
|
121
|
+
:method => verb,
|
|
122
|
+
:body => nil,
|
|
123
|
+
:url => "https://api.example.com/some-path"
|
|
124
|
+
})
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
shared_examples "normalizing arguments" do |verb|
|
|
131
|
+
context "when multiple path segments are passed" do
|
|
132
|
+
let(:segments) { ["first-segment", "next-segment"] }
|
|
133
|
+
|
|
134
|
+
context "when an options hash is not supplied" do
|
|
135
|
+
let(:args) { segments }
|
|
136
|
+
|
|
137
|
+
it "makes a request with the correct url and options" do
|
|
138
|
+
expect(rest_client).to receive(:request).with(verb, "first-segment/next-segment", {}) { [request, response] }
|
|
139
|
+
subject
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
context "when an options has is supplied" do
|
|
144
|
+
let(:args) { segments + [options] }
|
|
145
|
+
|
|
146
|
+
it "makes a request with the correct url and options" do
|
|
147
|
+
expect(rest_client).to receive(:request).with(verb, "first-segment/next-segment", options) { [request, response] }
|
|
148
|
+
subject
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
context "when a single path segment is passed" do
|
|
154
|
+
context "when an options hash is not supplied" do
|
|
155
|
+
let(:args) { ["first-segment"] }
|
|
156
|
+
|
|
157
|
+
it "makes a request with the correct url and options" do
|
|
158
|
+
expect(rest_client).to receive(:request).with(verb, "first-segment", {}) { [request, response] }
|
|
159
|
+
subject
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
context "when an options has is supplied" do
|
|
164
|
+
let(:args) { ["first-segment", options] }
|
|
165
|
+
|
|
166
|
+
it "makes a request with the correct url and options" do
|
|
167
|
+
expect(rest_client).to receive(:request).with(verb, "first-segment", options) { [request, response] }
|
|
168
|
+
subject
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
let(:response) { { :status => "201", :headers => { "some-header-key" => "some-header-value" }, :body => "some-body" } }
|
|
175
|
+
let(:request) do
|
|
176
|
+
{
|
|
177
|
+
:method => "GET",
|
|
178
|
+
:url => "http://api.example.com/some-path",
|
|
179
|
+
:headers => { "some-header-key" => "some-header-value" },
|
|
180
|
+
:body => "some-body"
|
|
181
|
+
}
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
describe "#get" do
|
|
185
|
+
subject { base.get(*args) }
|
|
186
|
+
|
|
187
|
+
it "makes a GET request" do
|
|
188
|
+
expect(rest_client).to receive(:request).with("GET", "some-path", options) { [request, response] }
|
|
189
|
+
subject
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
include_examples "handling responses", "GET"
|
|
193
|
+
include_examples "normalizing arguments", "GET"
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
describe "#post" do
|
|
197
|
+
subject { base.post(*args) }
|
|
198
|
+
|
|
199
|
+
it "makes a POST request" do
|
|
200
|
+
expect(rest_client).to receive(:request).with("POST", "some-path", options) { [request, response] }
|
|
201
|
+
subject
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
include_examples "handling responses", "POST"
|
|
205
|
+
include_examples "normalizing arguments", "POST"
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
describe "#put" do
|
|
209
|
+
subject { base.put(*args) }
|
|
210
|
+
|
|
211
|
+
it "makes a PUT request" do
|
|
212
|
+
expect(rest_client).to receive(:request).with("PUT", "some-path", options) { [request, response] }
|
|
213
|
+
subject
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
include_examples "handling responses", "PUT"
|
|
217
|
+
include_examples "normalizing arguments", "PUT"
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe "#delete" do
|
|
221
|
+
subject { base.delete(*args) }
|
|
222
|
+
|
|
223
|
+
it "makes a DELETE request" do
|
|
224
|
+
expect(rest_client).to receive(:request).with("DELETE", "some-path", options) { [request, response] }
|
|
225
|
+
subject
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
include_examples "handling responses", "DELETE"
|
|
229
|
+
include_examples "normalizing arguments", "DELETE"
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
describe "#resource_match" do
|
|
234
|
+
let(:fingerprints) { "some-fingerprints" }
|
|
235
|
+
|
|
236
|
+
it "makes a PUT request to the resource_match endpoint with the correct payload" do
|
|
237
|
+
stub = stub_request(:put, "https://api.example.com/v2/resource_match").
|
|
238
|
+
with(:body => fingerprints).
|
|
239
|
+
to_return(:body => "{}")
|
|
240
|
+
base.resource_match(fingerprints)
|
|
241
|
+
expect(stub).to have_been_requested
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
describe "#upload_app" do
|
|
246
|
+
let(:guid) { "some-guid" }
|
|
247
|
+
let(:bits) { "some-bits" }
|
|
248
|
+
let(:job_guid) { "123abc" }
|
|
249
|
+
let(:fake_zipfile) { File.new("#{SPEC_ROOT}/fixtures/empty_file") }
|
|
250
|
+
let(:upload_response) { %Q({"metadata":{"guid":"#{job_guid}"}}) }
|
|
251
|
+
|
|
252
|
+
def stub_upload
|
|
253
|
+
stub_request(:put, "https://api.example.com/v2/apps/#{guid}/bits?async=true"
|
|
254
|
+
).to_return(
|
|
255
|
+
:body => upload_response
|
|
256
|
+
)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def stub_poll
|
|
260
|
+
allow(base).to receive(:poll_upload_until_finished)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it "makes a PUT request to the app bits endpoint with the correct payload" do
|
|
264
|
+
upload_stub = stub_upload
|
|
265
|
+
stub_poll
|
|
266
|
+
base.upload_app(guid, fake_zipfile)
|
|
267
|
+
expect(upload_stub).to have_been_requested
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
context "when async is supported" do
|
|
271
|
+
it "polls the job until finished" do
|
|
272
|
+
stub_upload
|
|
273
|
+
status_stub = stub_request(:get, "https://api.example.com/v2/jobs/#{job_guid}"
|
|
274
|
+
).to_return(
|
|
275
|
+
{:body => {:entity => {:status => 'queued'}}.to_json},
|
|
276
|
+
{:body => {:entity => {:status => 'finished'}}.to_json}
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
base.upload_app(guid, fake_zipfile)
|
|
280
|
+
expect(status_stub).to have_been_requested.twice
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
context "when async is not supported" do
|
|
285
|
+
let(:upload_response) { "" }
|
|
286
|
+
|
|
287
|
+
it "does not explode" do
|
|
288
|
+
stub_upload
|
|
289
|
+
expect {
|
|
290
|
+
base.upload_app(guid, fake_zipfile)
|
|
291
|
+
}.not_to raise_exception
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
context "when there is no file to upload" do
|
|
296
|
+
it "does not include 'application' in the request hash" do
|
|
297
|
+
stub_poll
|
|
298
|
+
stub =
|
|
299
|
+
stub_request(
|
|
300
|
+
:put,
|
|
301
|
+
"https://api.example.com/v2/apps/#{guid}/bits?async=true"
|
|
302
|
+
).with { |request|
|
|
303
|
+
request.body =~ /name="resources"/ &&
|
|
304
|
+
request.body !~ /name="application"/
|
|
305
|
+
}.to_return(
|
|
306
|
+
:body => upload_response
|
|
307
|
+
)
|
|
308
|
+
base.upload_app(guid)
|
|
309
|
+
expect(stub).to have_been_requested
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
describe "#poll_upload_until_finished" do
|
|
315
|
+
let(:job_guid) { "123abc" }
|
|
316
|
+
|
|
317
|
+
it "makes a GET request" do
|
|
318
|
+
stub = WebMock::API.stub_request(:get, "https://api.example.com/v2/jobs/#{job_guid}"
|
|
319
|
+
).to_return(
|
|
320
|
+
:body => %q({"metadata":{"guid":"123abc"},"entity":{"status":"running"}})
|
|
321
|
+
).times(2).then.to_return(
|
|
322
|
+
:body => %q({"metadata":{"guid":"123abc"},"entity":{"status":"finished"}})
|
|
323
|
+
)
|
|
324
|
+
base.poll_upload_until_finished(job_guid)
|
|
325
|
+
expect(stub).to have_been_requested.times(3)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
it "raises CFoundry::BadResponse if upload fails" do
|
|
329
|
+
stub = WebMock::API.stub_request(:get, "https://api.example.com/v2/jobs/#{job_guid}"
|
|
330
|
+
).to_return(
|
|
331
|
+
:body => %q({"metadata":{"guid":"123abc"},"entity":{"status":"running"}})
|
|
332
|
+
).times(2).then.to_return(
|
|
333
|
+
:body => %q({"metadata":{"guid":"123abc"},"entity":{"status":"failed"}})
|
|
334
|
+
)
|
|
335
|
+
expect {
|
|
336
|
+
base.poll_upload_until_finished(job_guid)
|
|
337
|
+
}.to raise_error(CFoundry::BadResponse)
|
|
338
|
+
expect(stub).to have_been_requested.times(3)
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
describe "#stream_file" do
|
|
343
|
+
let(:app_guid) { "1234" }
|
|
344
|
+
let(:instance_guid) { "3456" }
|
|
345
|
+
let(:api_url) { "https://api.example.com/v2/apps/#{app_guid}/instances/#{instance_guid}/files/some/path/segments" }
|
|
346
|
+
let(:file_url) { "http://api.example.com/static/path/to/some/file" }
|
|
347
|
+
|
|
348
|
+
before do
|
|
349
|
+
allow(base).to receive(:token) { CFoundry::AuthToken.new("bearer foo") }
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
it "follows the redirect returned by the files endpoint" do
|
|
353
|
+
stub_request(:get, api_url).to_return(
|
|
354
|
+
:status => 301,
|
|
355
|
+
:headers => { "location" => file_url },
|
|
356
|
+
:body => ""
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
request =
|
|
360
|
+
stub_request(
|
|
361
|
+
:get, file_url + "&tail"
|
|
362
|
+
).with(
|
|
363
|
+
:headers => { "Accept" => "*/*", "Authorization" => "bearer foo" }
|
|
364
|
+
).to_return(
|
|
365
|
+
:status => 200,
|
|
366
|
+
:body => "some body chunks"
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
base.stream_file(app_guid, instance_guid, "some", "path", "segments") do |body|
|
|
370
|
+
expect(request).to have_been_made
|
|
371
|
+
expect(body).to eql("some body chunks")
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module CFoundry
|
|
4
|
+
module V2
|
|
5
|
+
describe Client do
|
|
6
|
+
subject(:client) { build(:client) }
|
|
7
|
+
|
|
8
|
+
describe "#register" do
|
|
9
|
+
let(:uaa) { UAAClient.new('http://uaa.example.com') }
|
|
10
|
+
let(:email) { "test@test.com" }
|
|
11
|
+
let(:password) { "secret" }
|
|
12
|
+
|
|
13
|
+
subject { client.register(email, password) }
|
|
14
|
+
|
|
15
|
+
it "creates the user in uaa and ccng" do
|
|
16
|
+
allow(client.base).to receive(:uaa) { uaa }
|
|
17
|
+
allow(uaa).to receive(:add_user).with(email, password, {}) { {:id => "1234"} }
|
|
18
|
+
|
|
19
|
+
user = build(:user)
|
|
20
|
+
allow(client).to receive(:user) { user }
|
|
21
|
+
allow(user).to receive(:create!)
|
|
22
|
+
subject
|
|
23
|
+
expect(user.guid).to eq "1234"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe "#current_user" do
|
|
28
|
+
subject { client.current_user }
|
|
29
|
+
before { client.token = token }
|
|
30
|
+
|
|
31
|
+
context "when there is no token" do
|
|
32
|
+
let(:token) { nil }
|
|
33
|
+
it { should eq nil }
|
|
34
|
+
end
|
|
35
|
+
|
|
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
|
|
40
|
+
|
|
41
|
+
context "when there is access_token_data" do
|
|
42
|
+
let(:token_data) { {:user_id => "123", :email => "guy@example.com"} }
|
|
43
|
+
let(:auth_header) { JWT.encode(token_data, nil, false) }
|
|
44
|
+
let(:token) do
|
|
45
|
+
CFoundry::AuthToken.new("bearer #{auth_header}", "some-refresh-token")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it { should be_a User }
|
|
49
|
+
|
|
50
|
+
describe '#guid' do
|
|
51
|
+
subject { super().guid }
|
|
52
|
+
it { should eq "123" }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe '#emails' do
|
|
56
|
+
subject { super().emails }
|
|
57
|
+
it { should eq [{:value => "guy@example.com"}] }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe "#version" do
|
|
63
|
+
describe '#version' do
|
|
64
|
+
subject { super().version }
|
|
65
|
+
it { should eq 2 }
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe "#login_prompts" do
|
|
70
|
+
include_examples "client login prompts"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe "#login" do
|
|
74
|
+
include_examples "client login"
|
|
75
|
+
|
|
76
|
+
it 'sets the current organization to nil' do
|
|
77
|
+
client.current_organization = "org"
|
|
78
|
+
expect { subject }.to change { client.current_organization }.from("org").to(nil)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'sets the current space to nil' do
|
|
82
|
+
client.current_space = "space"
|
|
83
|
+
expect { subject }.to change { client.current_space }.from("space").to(nil)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe "#target=" do
|
|
88
|
+
let(:new_target) { "some-target-url.com"}
|
|
89
|
+
|
|
90
|
+
it "sets a new target" do
|
|
91
|
+
expect{client.target = new_target}.to change {client.target}.from("http://api.example.com").to(new_target)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "sets a new target on the base client" do
|
|
95
|
+
expect{client.target = new_target}.to change{client.base.target}.from("http://api.example.com").to(new_target)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe "#service_instances" do
|
|
100
|
+
let(:client) { build(:client) }
|
|
101
|
+
|
|
102
|
+
it "includes user-provided instances" do
|
|
103
|
+
expect(client.base).to receive(:service_instances).with(hash_including(user_provided: true)).and_return([])
|
|
104
|
+
client.service_instances
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
describe "#make_service_instance" do
|
|
109
|
+
it "returns a UserProvidedServiceInstance when json[:type] is user_provided_service_instance" do
|
|
110
|
+
json = MultiJson.load(CcApiStub::Helper.load_fixtures(:fake_cc_user_provided_service_instance).to_json, :symbolize_keys => true)
|
|
111
|
+
instance = client.make_service_instance(json)
|
|
112
|
+
expect(instance).to be_a(CFoundry::V2::UserProvidedServiceInstance)
|
|
113
|
+
|
|
114
|
+
json = MultiJson.load(CcApiStub::Helper.load_fixtures(:fake_cc_managed_service_instance).to_json, :symbolize_keys => true)
|
|
115
|
+
instance = client.make_service_instance(json)
|
|
116
|
+
expect(instance).to be_a(CFoundry::V2::ManagedServiceInstance)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module CFoundry
|
|
4
|
+
module V2
|
|
5
|
+
describe Domain do
|
|
6
|
+
let(:space) { build(:space) }
|
|
7
|
+
let(:domain) { build(:domain, :spaces => [space]) }
|
|
8
|
+
|
|
9
|
+
it "should have a spaces association" do
|
|
10
|
+
expect(domain.spaces).to eq([space])
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "#owning_organization" do
|
|
14
|
+
context "when the domain is not persisted" do
|
|
15
|
+
let(:client) { build(:client) }
|
|
16
|
+
let(:domain) { build(:domain, client: client, guid: nil)}
|
|
17
|
+
it "asdf" do
|
|
18
|
+
expect(client).not_to receive(:owning_organization)
|
|
19
|
+
expect(client).to receive(:organization)
|
|
20
|
+
domain.owning_organization
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe "validations" do
|
|
26
|
+
subject { build(:domain) }
|
|
27
|
+
it { should validate_presence_of(:name) }
|
|
28
|
+
it { should allow_value("run.pivotal.io").for(:name) }
|
|
29
|
+
it { should_not allow_value("not-a-url").for(:name) }
|
|
30
|
+
it { should validate_presence_of(:owning_organization) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "#system?" do
|
|
34
|
+
let(:params) { {} }
|
|
35
|
+
let(:domain) { build(:domain, {:owning_organization => nil, client: client}.merge(params)) }
|
|
36
|
+
let(:client) { build(:client) }
|
|
37
|
+
|
|
38
|
+
context "when the domain is persisted and has no owning organization" do
|
|
39
|
+
it "returns true" do
|
|
40
|
+
expect(domain.system?).to be_truthy
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "when the domain is not persisted" do
|
|
45
|
+
let(:params) { {:guid => nil} }
|
|
46
|
+
|
|
47
|
+
it "returns false" do
|
|
48
|
+
expect(domain.system?).to be_falsey
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "when the domain has an owning org" do
|
|
53
|
+
let(:params) { {:owning_organization => org} }
|
|
54
|
+
let(:org) { build(:organization) }
|
|
55
|
+
|
|
56
|
+
it "returns false" do
|
|
57
|
+
expect(domain.system?).to be_falsey
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module CFoundry
|
|
4
|
+
module V2
|
|
5
|
+
describe Event do
|
|
6
|
+
let(:event) { build(:event, :app_update, changes: 'STOPPED') }
|
|
7
|
+
|
|
8
|
+
describe "#metadata" do
|
|
9
|
+
it "contains the request" do
|
|
10
|
+
expect(event.metadata[:request]).to eq('STOPPED')
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|