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.
Files changed (268) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +2 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +11 -0
  8. data/Checkfile +2 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE +987 -0
  11. data/NOTICE +10 -0
  12. data/README.md +9 -0
  13. data/Rakefile +14 -0
  14. data/VERSION +1 -0
  15. data/cfoundry.gemspec +41 -0
  16. data/config/locales/en.yml +168 -0
  17. data/lib/cc_api_stub/app_usage_events.rb +11 -0
  18. data/lib/cc_api_stub/applications.rb +57 -0
  19. data/lib/cc_api_stub/domains.rb +32 -0
  20. data/lib/cc_api_stub/events.rb +11 -0
  21. data/lib/cc_api_stub/frameworks.rb +22 -0
  22. data/lib/cc_api_stub/helper.rb +148 -0
  23. data/lib/cc_api_stub/login.rb +21 -0
  24. data/lib/cc_api_stub/organization_users.rb +27 -0
  25. data/lib/cc_api_stub/organizations.rb +82 -0
  26. data/lib/cc_api_stub/routes.rb +26 -0
  27. data/lib/cc_api_stub/runtimes.rb +22 -0
  28. data/lib/cc_api_stub/service_bindings.rb +22 -0
  29. data/lib/cc_api_stub/service_instances.rb +22 -0
  30. data/lib/cc_api_stub/services.rb +21 -0
  31. data/lib/cc_api_stub/space_users.rb +27 -0
  32. data/lib/cc_api_stub/spaces.rb +58 -0
  33. data/lib/cc_api_stub/users.rb +85 -0
  34. data/lib/cc_api_stub.rb +20 -0
  35. data/lib/cfoundry/auth_token.rb +62 -0
  36. data/lib/cfoundry/baseclient.rb +220 -0
  37. data/lib/cfoundry/chatty_hash.rb +46 -0
  38. data/lib/cfoundry/client.rb +42 -0
  39. data/lib/cfoundry/concerns/login_helpers.rb +14 -0
  40. data/lib/cfoundry/concerns/proxy_options.rb +14 -0
  41. data/lib/cfoundry/errors.rb +163 -0
  42. data/lib/cfoundry/rest_client.rb +316 -0
  43. data/lib/cfoundry/test_support.rb +3 -0
  44. data/lib/cfoundry/trace_helpers.rb +64 -0
  45. data/lib/cfoundry/uaaclient.rb +151 -0
  46. data/lib/cfoundry/upload_helpers.rb +222 -0
  47. data/lib/cfoundry/v2/app.rb +313 -0
  48. data/lib/cfoundry/v2/app_event.rb +13 -0
  49. data/lib/cfoundry/v2/app_instance.rb +74 -0
  50. data/lib/cfoundry/v2/app_usage_event.rb +14 -0
  51. data/lib/cfoundry/v2/base.rb +112 -0
  52. data/lib/cfoundry/v2/client.rb +104 -0
  53. data/lib/cfoundry/v2/domain.rb +20 -0
  54. data/lib/cfoundry/v2/event.rb +17 -0
  55. data/lib/cfoundry/v2/helper.rb +11 -0
  56. data/lib/cfoundry/v2/managed_service_instance.rb +13 -0
  57. data/lib/cfoundry/v2/model.rb +213 -0
  58. data/lib/cfoundry/v2/model_magic/attribute.rb +49 -0
  59. data/lib/cfoundry/v2/model_magic/client_extensions.rb +170 -0
  60. data/lib/cfoundry/v2/model_magic/has_summary.rb +49 -0
  61. data/lib/cfoundry/v2/model_magic/query_multi_value_helper.rb +21 -0
  62. data/lib/cfoundry/v2/model_magic/query_value_helper.rb +33 -0
  63. data/lib/cfoundry/v2/model_magic/queryable_by.rb +39 -0
  64. data/lib/cfoundry/v2/model_magic/to_many.rb +145 -0
  65. data/lib/cfoundry/v2/model_magic/to_one.rb +81 -0
  66. data/lib/cfoundry/v2/model_magic.rb +134 -0
  67. data/lib/cfoundry/v2/organization.rb +44 -0
  68. data/lib/cfoundry/v2/quota_definition.rb +12 -0
  69. data/lib/cfoundry/v2/route.rb +25 -0
  70. data/lib/cfoundry/v2/service.rb +22 -0
  71. data/lib/cfoundry/v2/service_auth_token.rb +9 -0
  72. data/lib/cfoundry/v2/service_binding.rb +10 -0
  73. data/lib/cfoundry/v2/service_broker.rb +12 -0
  74. data/lib/cfoundry/v2/service_instance.rb +14 -0
  75. data/lib/cfoundry/v2/service_plan.rb +16 -0
  76. data/lib/cfoundry/v2/space.rb +31 -0
  77. data/lib/cfoundry/v2/stack.rb +10 -0
  78. data/lib/cfoundry/v2/user.rb +97 -0
  79. data/lib/cfoundry/v2/user_provided_service_instance.rb +16 -0
  80. data/lib/cfoundry/validator.rb +41 -0
  81. data/lib/cfoundry/version.rb +4 -0
  82. data/lib/cfoundry/zip.rb +56 -0
  83. data/lib/cfoundry.rb +6 -0
  84. data/release_notes/release_1_5_3.md +177 -0
  85. data/release_notes/release_2.3.1.md +14 -0
  86. data/release_notes/release_2.3.3.md +38 -0
  87. data/release_notes/release_2.3.4.md +16 -0
  88. data/release_notes/release_2.3.5.md +14 -0
  89. data/release_notes/release_2.3.6.md +14 -0
  90. data/release_notes/release_2.3.6.rc1.md +29 -0
  91. data/release_notes/release_2.3.6.rc2.md +19 -0
  92. data/release_notes/release_2.3.7.rc1.md +14 -0
  93. data/release_notes/release_2.4.0.md +41 -0
  94. data/release_notes/release_2.4.1.rc1.md +58 -0
  95. data/release_notes/release_3.0.0.md +21 -0
  96. data/release_notes/release_3.0.1.md +16 -0
  97. data/release_notes/release_3.0.2.rc1.md +19 -0
  98. data/release_notes/release_4.0.0.md +19 -0
  99. data/release_notes/release_4.0.1.md +14 -0
  100. data/release_notes/release_4.0.2.rc1.md +14 -0
  101. data/release_notes/release_4.0.2.rc2.md +11 -0
  102. data/release_notes/release_4.0.2.rc3.md +11 -0
  103. data/release_notes/release_4.0.2.rc4.md +19 -0
  104. data/release_notes/release_4.0.2.rc5.md +14 -0
  105. data/release_notes/release_4.0.3.md +19 -0
  106. data/release_notes/release_4.0.4.rc1.md +14 -0
  107. data/release_notes/release_4.0.4.rc2.md +14 -0
  108. data/release_notes/release_4.1.0.md +19 -0
  109. data/release_notes/release_4.2.0.rc.md +24 -0
  110. data/release_notes/release_4.3.0.md +22 -0
  111. data/release_notes/release_4.3.1.md +14 -0
  112. data/release_notes/release_4.3.10.md +14 -0
  113. data/release_notes/release_4.3.11.md +14 -0
  114. data/release_notes/release_4.3.12.md +14 -0
  115. data/release_notes/release_4.3.2.rc1.md +21 -0
  116. data/release_notes/release_4.3.3.md +24 -0
  117. data/release_notes/release_4.3.4.md +11 -0
  118. data/release_notes/release_4.3.4.rc1.md +24 -0
  119. data/release_notes/release_4.3.5.md +36 -0
  120. data/release_notes/release_4.3.5.rc1.md +21 -0
  121. data/release_notes/release_4.3.6.md +14 -0
  122. data/release_notes/release_4.3.7.md +50 -0
  123. data/release_notes/release_4.3.8.md +19 -0
  124. data/release_notes/release_4.3.9.md +14 -0
  125. data/release_notes/release_4.4.0.md +16 -0
  126. data/release_notes/release_4.5.1.md +11 -0
  127. data/release_notes/release_4.5.2.md +14 -0
  128. data/release_notes/release_4.5.3.md +29 -0
  129. data/release_notes/release_4.6.0.md +24 -0
  130. data/release_notes/release_4.6.1.md +14 -0
  131. data/release_notes/release_4.6.2.md +16 -0
  132. data/release_notes/release_4.6.3.rc1.md +14 -0
  133. data/release_notes/release_4.6.3.rc2.md +14 -0
  134. data/release_notes/release_4.6.3.rc3.md +17 -0
  135. data/release_notes/release_4.7.0.md +11 -0
  136. data/release_notes/release_4.7.1.md +14 -0
  137. data/release_notes/release_4.7.1.rc.1.md +14 -0
  138. data/release_notes/release_4.7.1.rc1.md +19 -0
  139. data/script/gpp +3 -0
  140. data/spec/cc_api_stub/app_usage_events_spec.rb +12 -0
  141. data/spec/cc_api_stub/applications_spec.rb +69 -0
  142. data/spec/cc_api_stub/domains_spec.rb +40 -0
  143. data/spec/cc_api_stub/events_spec.rb +12 -0
  144. data/spec/cc_api_stub/frameworks_spec.rb +19 -0
  145. data/spec/cc_api_stub/login_spec.rb +20 -0
  146. data/spec/cc_api_stub/organization_users_spec.rb +35 -0
  147. data/spec/cc_api_stub/organizations_spec.rb +118 -0
  148. data/spec/cc_api_stub/routes_spec.rb +19 -0
  149. data/spec/cc_api_stub/runtimes_spec.rb +19 -0
  150. data/spec/cc_api_stub/service_bindings_spec.rb +13 -0
  151. data/spec/cc_api_stub/service_instances_spec.rb +19 -0
  152. data/spec/cc_api_stub/services_spec.rb +11 -0
  153. data/spec/cc_api_stub/space_users_spec.rb +35 -0
  154. data/spec/cc_api_stub/spaces_spec.rb +38 -0
  155. data/spec/cc_api_stub/users_spec.rb +107 -0
  156. data/spec/cfoundry/auth_token_spec.rb +153 -0
  157. data/spec/cfoundry/baseclient_spec.rb +284 -0
  158. data/spec/cfoundry/client_spec.rb +13 -0
  159. data/spec/cfoundry/errors_spec.rb +117 -0
  160. data/spec/cfoundry/rest_client_spec.rb +367 -0
  161. data/spec/cfoundry/trace_helpers_spec.rb +91 -0
  162. data/spec/cfoundry/uaaclient_spec.rb +421 -0
  163. data/spec/cfoundry/upload_helpers_spec.rb +182 -0
  164. data/spec/cfoundry/v2/app_event_spec.rb +97 -0
  165. data/spec/cfoundry/v2/app_instance_spec.rb +31 -0
  166. data/spec/cfoundry/v2/app_spec.rb +354 -0
  167. data/spec/cfoundry/v2/app_usage_event_spec.rb +15 -0
  168. data/spec/cfoundry/v2/base_spec.rb +375 -0
  169. data/spec/cfoundry/v2/client_spec.rb +121 -0
  170. data/spec/cfoundry/v2/domain_spec.rb +63 -0
  171. data/spec/cfoundry/v2/event_spec.rb +15 -0
  172. data/spec/cfoundry/v2/managed_service_instance_spec.rb +149 -0
  173. data/spec/cfoundry/v2/model_magic/attribute_spec.rb +123 -0
  174. data/spec/cfoundry/v2/model_magic/has_summary_spec.rb +17 -0
  175. data/spec/cfoundry/v2/model_magic/to_many_spec.rb +53 -0
  176. data/spec/cfoundry/v2/model_magic/to_one_spec.rb +106 -0
  177. data/spec/cfoundry/v2/model_magic_spec.rb +43 -0
  178. data/spec/cfoundry/v2/model_spec.rb +472 -0
  179. data/spec/cfoundry/v2/organization_spec.rb +282 -0
  180. data/spec/cfoundry/v2/quota_definition_spec.rb +50 -0
  181. data/spec/cfoundry/v2/route_spec.rb +42 -0
  182. data/spec/cfoundry/v2/service_plan_spec.rb +53 -0
  183. data/spec/cfoundry/v2/service_spec.rb +58 -0
  184. data/spec/cfoundry/v2/space_spec.rb +160 -0
  185. data/spec/cfoundry/v2/user_provided_service_instance_spec.rb +57 -0
  186. data/spec/cfoundry/v2/user_spec.rb +206 -0
  187. data/spec/cfoundry/validator_spec.rb +94 -0
  188. data/spec/factories/app_events_factory.rb +7 -0
  189. data/spec/factories/app_usage_events_factory.rb +32 -0
  190. data/spec/factories/apps_factory.rb +11 -0
  191. data/spec/factories/clients_factory.rb +7 -0
  192. data/spec/factories/domains_factory.rb +10 -0
  193. data/spec/factories/events_factory.rb +50 -0
  194. data/spec/factories/organizations_factory.rb +12 -0
  195. data/spec/factories/quota_definitions_factory.rb +8 -0
  196. data/spec/factories/routes_factory.rb +10 -0
  197. data/spec/factories/service_instances_factory.rb +10 -0
  198. data/spec/factories/service_plans_factory.rb +10 -0
  199. data/spec/factories/services_factory.rb +10 -0
  200. data/spec/factories/spaces_factory.rb +10 -0
  201. data/spec/factories/user_provided_service_instances_factory.rb +10 -0
  202. data/spec/factories/users_factory.rb +10 -0
  203. data/spec/fixtures/apps/with_cfignore/.cfignore +4 -0
  204. data/spec/fixtures/apps/with_cfignore/.hidden_file +1 -0
  205. data/spec/fixtures/apps/with_cfignore/ambiguous_ignored +0 -0
  206. data/spec/fixtures/apps/with_cfignore/ignored_dir/file_in_ignored_dir.txt +1 -0
  207. data/spec/fixtures/apps/with_cfignore/ignored_file.txt +1 -0
  208. data/spec/fixtures/apps/with_cfignore/non_ignored_dir/file_in_non_ignored_dir.txt +1 -0
  209. data/spec/fixtures/apps/with_cfignore/non_ignored_dir/ignored_file.txt +1 -0
  210. data/spec/fixtures/apps/with_cfignore/non_ignored_dir/toplevel_ignored.txt +0 -0
  211. data/spec/fixtures/apps/with_cfignore/non_ignored_file.txt +1 -0
  212. data/spec/fixtures/apps/with_cfignore/toplevel_ignored.txt +0 -0
  213. data/spec/fixtures/apps/with_dotfiles/.dotfile +1 -0
  214. data/spec/fixtures/apps/with_dotfiles/xyz +1 -0
  215. data/spec/fixtures/apps/with_external_symlink/foo +1 -0
  216. data/spec/fixtures/apps/with_ignored_external_symlink/.cfignore +1 -0
  217. data/spec/fixtures/apps/with_ignored_external_symlink/foo +1 -0
  218. data/spec/fixtures/apps/with_nested_directories/foo/bar/baz/fizz +0 -0
  219. data/spec/fixtures/apps/with_nested_directories/xyz +0 -0
  220. data/spec/fixtures/empty_file +0 -0
  221. data/spec/fixtures/fake_cc_app_usage_events.json +152 -0
  222. data/spec/fixtures/fake_cc_application.json +20 -0
  223. data/spec/fixtures/fake_cc_application_summary.json +56 -0
  224. data/spec/fixtures/fake_cc_created_application.json +11 -0
  225. data/spec/fixtures/fake_cc_created_domain.json +15 -0
  226. data/spec/fixtures/fake_cc_created_organization.json +11 -0
  227. data/spec/fixtures/fake_cc_created_route.json +13 -0
  228. data/spec/fixtures/fake_cc_created_service_instance.json +11 -0
  229. data/spec/fixtures/fake_cc_created_space.json +11 -0
  230. data/spec/fixtures/fake_cc_created_user.json +11 -0
  231. data/spec/fixtures/fake_cc_domain.json +55 -0
  232. data/spec/fixtures/fake_cc_domain_spaces.json +27 -0
  233. data/spec/fixtures/fake_cc_empty_search.json +7 -0
  234. data/spec/fixtures/fake_cc_events.json +419 -0
  235. data/spec/fixtures/fake_cc_frameworks.json +20 -0
  236. data/spec/fixtures/fake_cc_managed_service_instance.json +83 -0
  237. data/spec/fixtures/fake_cc_organization.json +161 -0
  238. data/spec/fixtures/fake_cc_organization_domains.json +59 -0
  239. data/spec/fixtures/fake_cc_organization_search.json +37 -0
  240. data/spec/fixtures/fake_cc_organization_spaces.json +99 -0
  241. data/spec/fixtures/fake_cc_organization_summary.json +20 -0
  242. data/spec/fixtures/fake_cc_organization_users.json +81 -0
  243. data/spec/fixtures/fake_cc_route.json +16 -0
  244. data/spec/fixtures/fake_cc_runtimes.json +20 -0
  245. data/spec/fixtures/fake_cc_service_binding.json +22 -0
  246. data/spec/fixtures/fake_cc_service_bindings.json +24 -0
  247. data/spec/fixtures/fake_cc_service_instance.json +83 -0
  248. data/spec/fixtures/fake_cc_service_instances.json +72 -0
  249. data/spec/fixtures/fake_cc_services.json +160 -0
  250. data/spec/fixtures/fake_cc_space.json +45 -0
  251. data/spec/fixtures/fake_cc_space_apps.json +49 -0
  252. data/spec/fixtures/fake_cc_space_summary.json +84 -0
  253. data/spec/fixtures/fake_cc_spaces.json +92 -0
  254. data/spec/fixtures/fake_cc_stats.json +29 -0
  255. data/spec/fixtures/fake_cc_user.json +139 -0
  256. data/spec/fixtures/fake_cc_user_organizations.json +92 -0
  257. data/spec/fixtures/fake_cc_user_provided_service_instance.json +51 -0
  258. data/spec/fixtures/fake_cc_user_with_managers.json +85 -0
  259. data/spec/integration/client_spec.rb +38 -0
  260. data/spec/spec_helper.rb +22 -0
  261. data/spec/support/factory_girl.rb +6 -0
  262. data/spec/support/shared_examples/cc_api_stub_request_examples.rb +79 -0
  263. data/spec/support/shared_examples/client_login_examples.rb +46 -0
  264. data/spec/support/shared_examples/model_summary_examples.rb +34 -0
  265. data/spec/support/test_model_builder.rb +10 -0
  266. data/vendor/errors/v1.yml +189 -0
  267. data/vendor/errors/v2.yml +845 -0
  268. metadata +712 -0
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Errors' do
4
+ describe CFoundry::Timeout do
5
+ let(:parent) { Timeout::Error.new }
6
+
7
+ subject { CFoundry::Timeout.new("POST", '/blah', parent) }
8
+
9
+ describe '#to_s' do
10
+ subject { super().to_s }
11
+ it { should eq "POST /blah timed out" }
12
+ end
13
+
14
+ describe '#method' do
15
+ subject { super().method }
16
+ it { should eq "POST" }
17
+ end
18
+
19
+ describe '#uri' do
20
+ subject { super().uri }
21
+ it { should eq '/blah' }
22
+ end
23
+
24
+ describe '#parent' do
25
+ subject { super().parent }
26
+ it { should eq parent }
27
+ end
28
+ end
29
+
30
+ describe CFoundry::InvalidTarget do
31
+ let(:target) { "http://--foo-bar" }
32
+ subject { CFoundry::InvalidTarget.new(target) }
33
+
34
+ describe '#to_s' do
35
+ subject { super().to_s }
36
+ it { should eq "Invalid target URI: #{target}"}
37
+ end
38
+
39
+ describe '#target' do
40
+ subject { super().target }
41
+ it { should eq target }
42
+ end
43
+ end
44
+
45
+ describe CFoundry::APIError do
46
+ let(:request) { { :method => "GET", :url => "http://api.example.com/foo", :headers => {} } }
47
+ let(:response_body) { "NOT FOUND" }
48
+ let(:response) { { :status => 404, :headers => {}, :body => response_body } }
49
+
50
+ subject { CFoundry::APIError.new(nil, nil, request, response) }
51
+
52
+ describe '#to_s' do
53
+ subject { super().to_s }
54
+ it { should eq "404: NOT FOUND" }
55
+ end
56
+
57
+ describe '#request' do
58
+ subject { super().request }
59
+ it { should eq request }
60
+ end
61
+
62
+ describe '#response' do
63
+ subject { super().response }
64
+ it { should eq response }
65
+ end
66
+
67
+ describe "#initialize" do
68
+
69
+ context "Response body is JSON" do
70
+
71
+ let(:response_body) { "{\"description\":\"Something went wrong\"}"}
72
+
73
+ it "sets description to description field in parsed JSON" do
74
+ expect(CFoundry::APIError.new(nil, nil, request, response).description).to eq("Something went wrong")
75
+ end
76
+ end
77
+
78
+
79
+ context "Response body is not JSON" do
80
+
81
+ let(:response_body) { "Some plain text"}
82
+
83
+ it "sets description to body text" do
84
+ expect(CFoundry::APIError.new(nil, nil, request, response).description).to eq("Some plain text")
85
+ end
86
+ end
87
+
88
+ it "allows override of description" do
89
+ expect(CFoundry::APIError.new("My description", nil, request, response).description).to eq("My description")
90
+ end
91
+
92
+ end
93
+
94
+ describe "#request_trace" do
95
+ describe '#request_trace' do
96
+ subject { super().request_trace }
97
+ it { should include "REQUEST: " }
98
+ end
99
+ end
100
+
101
+ describe "#response_trace" do
102
+ describe '#response_trace' do
103
+ subject { super().response_trace }
104
+ it { should include "RESPONSE: " }
105
+ end
106
+ end
107
+
108
+ it "sets error code to response error code by default" do
109
+ expect(CFoundry::APIError.new(nil, nil, request, response).error_code).to eq(404)
110
+ end
111
+
112
+ it "allows override of error code" do
113
+ expect(CFoundry::APIError.new(nil, 303, request, response).error_code).to eq(303)
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,367 @@
1
+ require "spec_helper"
2
+
3
+ describe CFoundry::RestClient do
4
+ let(:token) { nil }
5
+ let(:target) { "https://api.example.com" }
6
+ let(:rest_client) { CFoundry::RestClient.new(target, token) }
7
+
8
+ describe '#request' do
9
+ let(:path) { "some-path" }
10
+ let(:url) { "#{target}/#{path}" }
11
+ let(:verb) { "GET" }
12
+ let(:options) { {} }
13
+
14
+ def check_request(verb = :get, &block)
15
+ request_stub = stub_request(verb, url).to_return do |req|
16
+ block.call(req)
17
+ {}
18
+ end
19
+ subject
20
+ expect(request_stub).to have_been_requested
21
+ end
22
+
23
+ subject { rest_client.request(verb, path, options) }
24
+
25
+ describe 'headers' do
26
+ %w[Authorization X-Request-Id Content-Type].each do |header_name|
27
+ it "should not include the #{header_name} by default" do
28
+ check_request do |req|
29
+ expect(req.headers).not_to have_key(header_name)
30
+ end
31
+ end
32
+ end
33
+
34
+ it "should not provide specific accept mimetypes by default" do
35
+ check_request do |req|
36
+ expect(req.headers["Accept"]).to eql("*/*")
37
+ end
38
+ end
39
+
40
+ it 'should always include a content length' do
41
+ check_request do |req|
42
+ expect(req.headers["Content-Length"]).to eql(0)
43
+ end
44
+ end
45
+
46
+ context "when a payload is passed" do
47
+ context "when the payload is a string" do
48
+ let(:options) { { :payload => "some payload"} }
49
+
50
+ it 'includes a content length matching the payload size' do
51
+ check_request do |req|
52
+ expect(req.headers["Content-Length"]).to eql("some payload".length)
53
+ end
54
+ end
55
+ end
56
+
57
+ context "when the payload is a hash and the content-type is JSON" do
58
+ let(:options) { { :payload => { "key" => "value" }, :content => :json } }
59
+
60
+ it 'includes a content length matching the JSON encoded length' do
61
+ check_request do |req|
62
+ expect(req.headers["Content-Length"]).to eql('{"key":"value"}'.length)
63
+ end
64
+ end
65
+ end
66
+
67
+ context "when the payload is a hash (i.e. multipart upload)" do
68
+ let(:verb) { "PUT" }
69
+ let(:options) { {:payload => {"key" => "value"}} }
70
+
71
+ it 'includes a nonzero content length' do
72
+ check_request(:put) do |req|
73
+ expect(req.headers["Content-Length"].to_i).to be > 0
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ context "when params are passed" do
80
+ context "when params is an empty hash" do
81
+ let(:options) { {:params => {}} }
82
+
83
+ it "does not add a query string delimiter (the question mark)" do
84
+ request_stub = stub_request(:get, "https://api.example.com/some-path")
85
+ subject
86
+ expect(request_stub).to have_been_requested
87
+ end
88
+ end
89
+
90
+ context "when params has values" do
91
+ let(:options) { {:params => {"key" => "value"}} }
92
+
93
+ it "appends a query string and delimiter" do
94
+ request_stub = stub_request(:get, "https://api.example.com/some-path?key=value")
95
+ subject
96
+ expect(request_stub).to have_been_requested
97
+ end
98
+ end
99
+ end
100
+
101
+ context 'and the token is set' do
102
+ let(:token_header) { "bearer something" }
103
+ let(:token) { CFoundry::AuthToken.new(token_header) }
104
+
105
+ it 'should include Authorization in the header' do
106
+ check_request do |req|
107
+ expect(req.headers["Authorization"]).to eq(token_header)
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'and the request_id is set' do
113
+ before { rest_client.request_id = "SomeRequestId" }
114
+
115
+ it 'should include X-Request-Id in the header' do
116
+ check_request do |req|
117
+ expect(req.headers["X-Request-Id"]).to eq "SomeRequestId"
118
+ end
119
+ end
120
+ end
121
+
122
+ context 'and the content is passed in' do
123
+ let(:options) { {:content => "text/xml"} }
124
+
125
+ it 'should include Content-Type in the header' do
126
+ check_request do |req|
127
+ expect(req.headers["Content-Type"]).to eq "text/xml"
128
+ end
129
+ end
130
+ end
131
+
132
+ context 'and custom headers are passed in' do
133
+ let(:options) { {:headers => {"X-Foo" => "Bar"}} }
134
+
135
+ it 'should include the custom header in the header' do
136
+ check_request do |req|
137
+ expect(req.headers["X-Foo"]).to eq "Bar"
138
+ end
139
+ end
140
+
141
+ context 'and it overrides an existing one' do
142
+ let(:options) { {:content => "text/xml", :headers => {"Content-Type" => "text/html"}} }
143
+
144
+ it 'uses the custom header' do
145
+ check_request do |req|
146
+ expect(req.headers["Content-Type"]).to eq "text/html"
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ describe 'errors' do
154
+ context "when the target refuses the connection" do
155
+ let(:target) { "http://localhost:2358974958" }
156
+
157
+ it "raises CFoundry::TargetRefused" do
158
+ stub_request(:get, url).to_raise(Errno::ECONNREFUSED)
159
+ expect { subject }.to raise_error(CFoundry::TargetRefused)
160
+ end
161
+ end
162
+
163
+ context "when the target is not a HTTP(S) URI" do
164
+ let(:target) { "ftp://foo-bar.com" }
165
+
166
+ it "raises CFoundry::InvalidTarget" do
167
+ expect { subject }.to raise_error(CFoundry::InvalidTarget)
168
+ end
169
+ end
170
+
171
+ context "when the target URI is invalid" do
172
+ let(:target) { "@#*#^! rubby" }
173
+
174
+ it "raises CFoundry::InvalidTarget" do
175
+ expect { subject }.to raise_error(CFoundry::InvalidTarget)
176
+ end
177
+ end
178
+ end
179
+
180
+ describe "the return value" do
181
+ before do
182
+ stub_request(:get, url).to_return({
183
+ :status => 201,
184
+ :headers => {"Content-Type" => "application/json"},
185
+ :body => '{ "foo": 1 }'
186
+ })
187
+ end
188
+
189
+ it "returns a request hash and a response hash" do
190
+ expect(subject).to be_an(Array)
191
+ expect(subject.length).to eq(2)
192
+ end
193
+
194
+ describe "the returned request hash" do
195
+ it "returns a hash of :headers, :url, :body and :verb" do
196
+ expect(subject[0]).to eq({
197
+ :url => url,
198
+ :method => "GET",
199
+ :headers => {"Content-Length" => 0},
200
+ :body => nil
201
+ })
202
+ end
203
+ end
204
+
205
+ describe "the returned response hash" do
206
+ it "returns a hash of :headers, :status, :body" do
207
+ expect(subject[1]).to eq({
208
+ :status => "201",
209
+ :headers => {"content-type" => "application/json"},
210
+ :body => '{ "foo": 1 }'
211
+ })
212
+ end
213
+ end
214
+ end
215
+
216
+ describe "when the path starts with a slash" do
217
+ let(:path) { "/some-path/some-segment" }
218
+
219
+ it "doesn't add a double slash" do
220
+ stub = stub_request(:get, "https://api.example.com/some-path/some-segment")
221
+ subject
222
+ expect(stub).to have_been_requested
223
+ end
224
+ end
225
+
226
+ describe "when the path does not start with a slash" do
227
+ let(:path) { "some-path/some-segment" }
228
+
229
+ it "doesn't add a double slash" do
230
+ stub = stub_request(:get, "https://api.example.com/some-path/some-segment")
231
+ subject
232
+ expect(stub).to have_been_requested
233
+ end
234
+ end
235
+
236
+ describe "when the path is a full url" do
237
+ let(:path) { "http://example.com" }
238
+
239
+ it "requests the given url" do
240
+ stub = stub_request(:get, "http://example.com")
241
+ subject
242
+ expect(stub).to have_been_requested
243
+ end
244
+ end
245
+
246
+ describe "when the path is malformed" do
247
+ let(:path) { "#%&*$(#%&$%)" }
248
+
249
+ it "blows up" do
250
+ expect { subject }.to raise_error(URI::InvalidURIError)
251
+ end
252
+ end
253
+
254
+ describe 'trace' do
255
+ before do
256
+ rest_client.trace = true
257
+ stub_request(:get, url).to_return(:status => 200, :headers => {"content-type" => "application/json"}, :body => '{"some": "json"}')
258
+ end
259
+
260
+ it "prints the request and the response" do
261
+ expect(rest_client).to receive(:print_request).with({:headers => {"Content-Length" => 0}, :url => "https://api.example.com/some-path", :method => "GET", :body => nil})
262
+ expect(rest_client).to receive(:print_response).with({:status => "200", :headers => {"content-type" => "application/json"}, :body => '{"some": "json"}'})
263
+ subject
264
+ end
265
+ end
266
+
267
+ describe "following redirects" do
268
+ before do
269
+ stub_request(:post, "https://api.example.com/apps").to_return(
270
+ :status => 301,
271
+ :headers => {"location" => "https://api.example.com/apps/some-guid"}
272
+ )
273
+ stub_request(:get, "https://api.example.com/apps/some-guid").to_return(
274
+ :status => 200,
275
+ :body => '{"some": "json"}'
276
+ )
277
+ end
278
+
279
+ it "follows redirects correctly, returning the response to the 2nd redirect" do
280
+ request, response = rest_client.request("POST", "apps")
281
+ expect(response).to eql(
282
+ :status => "200",
283
+ :headers => {},
284
+ :body => '{"some": "json"}'
285
+ )
286
+ end
287
+ end
288
+ end
289
+
290
+ describe CFoundry::RestClient::HTTPFactory do
291
+ describe ".create" do
292
+ let(:proxy_options) { [] }
293
+ let(:target_uri) { "http://api.example.com" }
294
+
295
+ subject { CFoundry::RestClient::HTTPFactory.create(URI.parse(target_uri), proxy_options) }
296
+
297
+ context "when no proxy URI is set" do
298
+ before do
299
+ @original_no_proxy_env = ENV["NO_PROXY"]
300
+ ENV["NO_PROXY"] = "example.com"
301
+ end
302
+
303
+ after do
304
+ ENV["NO_PROXY"] = @original_no_proxy_env
305
+ end
306
+
307
+ it "should return an instance of the plain Net:HTTP class" do
308
+ expect(subject).to be_instance_of(Net::HTTP)
309
+ expect(subject.use_ssl?).to be_falsey
310
+ expect(subject.proxy?).to_not be_truthy
311
+ end
312
+ end
313
+
314
+ context "when the target is an https URI" do
315
+ before do
316
+ @original_no_proxy_env = ENV["NO_PROXY"]
317
+ ENV["NO_PROXY"] = "example.com"
318
+ end
319
+
320
+ after do
321
+ ENV["NO_PROXY"] = @original_no_proxy_env
322
+ end
323
+
324
+ let(:target_uri) { "https://example.com" }
325
+ it "should return an instance of the plain Net:HTTP class with use_ssl" do
326
+ expect(subject).to be_instance_of(Net::HTTP)
327
+ expect(subject.use_ssl?).to be_truthy
328
+ expect(subject.proxy?).to_not be_truthy
329
+ end
330
+ end
331
+
332
+ context "when a http proxy URI without user/password is set " do
333
+ let(:proxy_options) { ["exapmle.com", 8080, nil, nil] }
334
+
335
+ it "should return an instance of the proxy class" do
336
+ expect(subject.proxy?).to be_truthy
337
+ expect(subject.proxy_address).to eql("exapmle.com")
338
+ expect(subject.proxy_port).to eql(8080)
339
+ end
340
+ end
341
+
342
+ context "when a http proxy URI with user/password is set " do
343
+ let(:proxy_options) { ["exapmle.com", "8080", "user", "pass"] }
344
+
345
+ it "should return an instance of the proxy class" do
346
+ expect(subject.proxy?).to be_truthy
347
+ expect(subject.proxy_user).to eql("user")
348
+ expect(subject.proxy_pass).to eql("pass")
349
+ end
350
+ end
351
+ end
352
+ end
353
+
354
+ describe "#target=" do
355
+ let(:token) { "some-token" }
356
+
357
+ it "invalidates the token if the target has changed" do
358
+ rest_client.target = "http://some-target.com"
359
+ expect(rest_client.token).to be_nil
360
+ end
361
+
362
+ it "does not invalidate the token if the target has not changed" do
363
+ rest_client.target = target
364
+ expect(rest_client.token).to eq token
365
+ end
366
+ end
367
+ end
@@ -0,0 +1,91 @@
1
+ require "spec_helper"
2
+
3
+ describe CFoundry::TraceHelpers do
4
+ let(:tracehelper_test_class) { Class.new { include CFoundry::TraceHelpers } }
5
+ let(:request) do
6
+ {
7
+ :method => "GET",
8
+ :url => "http://api.example.com/foo",
9
+ :headers => { "bb-foo" => "bar", "accept" => "*/*" }
10
+ }
11
+ end
12
+ let(:response) { { :status => 404, :body => "not found", :headers => {} } }
13
+
14
+ shared_examples "request_trace tests" do
15
+ it { should include request_trace }
16
+ it { should include header_trace }
17
+ it { should include body_trace }
18
+ end
19
+
20
+ shared_examples "response_trace tests" do
21
+ before { response[:body] = response_body }
22
+
23
+ it "traces the provided response" do
24
+ expect(tracehelper_test_class.new.response_trace(response)).to eq(response_trace)
25
+ end
26
+ end
27
+
28
+ describe "#request_trace" do
29
+ let(:request_trace) { "REQUEST: GET http://api.example.com/foo" }
30
+ let(:header_trace) { "REQUEST_HEADERS:\n accept : */*\n bb-foo : bar" }
31
+ let(:body_trace) { "" }
32
+
33
+ subject { tracehelper_test_class.new.request_trace(request) }
34
+
35
+ context "without a request body" do
36
+ include_examples "request_trace tests"
37
+ end
38
+
39
+ context "with a request body" do
40
+ let(:body_trace) { "REQUEST_BODY: Some body text" }
41
+
42
+ before { request[:body] = "Some body text" }
43
+
44
+ include_examples "request_trace tests"
45
+ end
46
+
47
+ it "returns nil if request is nil" do
48
+ expect(tracehelper_test_class.new.request_trace(nil)).to eq(nil)
49
+ end
50
+
51
+ context "with protected attributes" do
52
+ let(:header_trace) { "REQUEST_HEADERS:\n Authorization : [PRIVATE DATA HIDDEN]" }
53
+ let(:request) do
54
+ {
55
+ :method => "GET",
56
+ :url => "http://api.example.com/foo",
57
+ :headers => { 'Authorization' => "SECRET STUFF" }
58
+ }
59
+ end
60
+ include_examples "request_trace tests"
61
+ end
62
+ end
63
+
64
+
65
+ describe "#response_trace" do
66
+ context "with a non-JSON response body" do
67
+ let(:response_trace) { "RESPONSE: [404]\nRESPONSE_HEADERS:\n\nRESPONSE_BODY:\nSome body" }
68
+ let(:response_body) { "Some body"}
69
+
70
+ include_examples "response_trace tests"
71
+ end
72
+
73
+ context "with a JSON response body" do
74
+ let(:response_body) { "{\"name\": \"vcap\",\"build\": 2222,\"support\": \"http://support.example.com\"}" }
75
+ let(:response_trace) { "RESPONSE: [404]\nRESPONSE_HEADERS:\n\nRESPONSE_BODY:\n#{MultiJson.dump(MultiJson.load(response_body), :pretty => true)}" }
76
+
77
+ include_examples "response_trace tests"
78
+ end
79
+
80
+ context "with credentials in the response body" do
81
+ let(:response_body) { '{"resources": [{"entity": {"credentials": {"super_secret_stuff": "goes here"}, "other_stuff": "still here"}}]}' }
82
+ let(:response_trace) { "RESPONSE: [404]\nRESPONSE_HEADERS:\n\nRESPONSE_BODY:\n#{MultiJson.dump({"resources" => [{"entity" => {"credentials" => "[PRIVATE DATA HIDDEN]", "other_stuff" => "still here"}}]}, :pretty => true)}" }
83
+
84
+ include_examples "response_trace tests"
85
+ end
86
+
87
+ it "returns nil if response is nil" do
88
+ expect(tracehelper_test_class.new.response_trace(nil)).to eq(nil)
89
+ end
90
+ end
91
+ end