new_cfoundry 4.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (269) 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 +40 -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 +63 -0
  36. data/lib/cfoundry/baseclient.rb +216 -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 +17 -0
  41. data/lib/cfoundry/errors.rb +163 -0
  42. data/lib/cfoundry/rest_client.rb +317 -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 +160 -0
  46. data/lib/cfoundry/upload_helpers.rb +222 -0
  47. data/lib/cfoundry/v2/app.rb +303 -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 +108 -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 +12 -0
  57. data/lib/cfoundry/v2/model.rb +211 -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 +138 -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 +30 -0
  77. data/lib/cfoundry/v2/stack.rb +10 -0
  78. data/lib/cfoundry/v2/user.rb +93 -0
  79. data/lib/cfoundry/v2/user_provided_service_instance.rb +15 -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 +5 -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 +154 -0
  157. data/spec/cfoundry/baseclient_spec.rb +298 -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 +349 -0
  161. data/spec/cfoundry/trace_helpers_spec.rb +91 -0
  162. data/spec/cfoundry/uaaclient_spec.rb +435 -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 +434 -0
  179. data/spec/cfoundry/v2/organization_spec.rb +135 -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 +13 -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/README.md +4 -0
  267. data/vendor/errors/v1.yml +189 -0
  268. data/vendor/errors/v2.yml +384 -0
  269. metadata +693 -0
@@ -0,0 +1,434 @@
1
+ require "spec_helper"
2
+
3
+ module CFoundry
4
+ module V2
5
+
6
+ # be careful, there is a TestModel in global scope because of the TestModelBuilder
7
+ class TestModel < CFoundry::V2::Model
8
+ attribute :foo, :string
9
+ to_one :domain
10
+
11
+ def create_endpoint_name
12
+ :odd_endpoint
13
+ end
14
+ end
15
+
16
+ class DefaultTestModel < CFoundry::V2::Model
17
+ attribute :foo, :string
18
+ end
19
+
20
+ describe Model do
21
+ let(:client) { build(:client) }
22
+ let(:guid) { "my-object-guid" }
23
+ let(:manifest) { {:metadata => {:guid => "some-guid-1"}, :entity => {}} }
24
+ let(:model) { TestModel.new(guid, client, manifest) }
25
+
26
+ describe "create" do
27
+ it "uses #create!" do
28
+ expect(model).to receive(:create!)
29
+ model.create
30
+ end
31
+
32
+ context "without errors" do
33
+ it "returns true" do
34
+ expect(model).to receive(:create!)
35
+ expect(model.create).to eq(true)
36
+ end
37
+ end
38
+
39
+ context "with errors" do
40
+ before do
41
+ allow(model.class).to receive(:model_name) { ActiveModel::Name.new(model, nil, "abstract_model") }
42
+ allow(model).to receive(:create!) { raise CFoundry::APIError.new("HELP") }
43
+ end
44
+
45
+ it "does not raise an exception" do
46
+ expect { model.create }.to_not raise_error
47
+ end
48
+
49
+ it "returns false" do
50
+ expect(model.create).to eq(false)
51
+ end
52
+
53
+ context "without model-specific errors" do
54
+ it "adds generic base error " do
55
+ model.create
56
+ expect(model.errors.full_messages.first).to match(/cloud controller reported an error/i)
57
+ end
58
+ end
59
+
60
+ context "with model-specific errors" do
61
+ it "does not set the generic error on base" do
62
+ model.create
63
+ expect(model.errors.size).to eq(1)
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#create!" do
70
+ before do
71
+ allow(client.base).to receive(:post) {
72
+ {:metadata => {
73
+ :guid => "123",
74
+ :created_at => "2013-06-10 10:41:15 -0700",
75
+ :updated_at => "2015-06-10 10:41:15 -0700"
76
+ }}
77
+ }
78
+ model.foo = "bar"
79
+ end
80
+
81
+ it "posts to the model's create url with appropriate arguments" do
82
+ expect(client.base).to receive(:post).with("v2", :odd_endpoint,
83
+ :content => :json,
84
+ :accept => :json,
85
+ :payload => {:foo => "bar"}
86
+ ) { {:metadata => {}} }
87
+ model.create!
88
+ end
89
+
90
+ it "clears diff" do
91
+ expect(model.diff).to be_present
92
+ model.create!
93
+ expect(model.diff).not_to be_present
94
+ end
95
+
96
+ it "sets manifest from the response" do
97
+ model.create!
98
+ expect(model.manifest).to eq({
99
+ :metadata => {
100
+ :guid => "123",
101
+ :created_at => "2013-06-10 10:41:15 -0700",
102
+ :updated_at => "2015-06-10 10:41:15 -0700"
103
+ }
104
+ })
105
+ end
106
+
107
+ it "sets guid from the response metadata" do
108
+ model.create!
109
+ expect(model.guid).to eq("123")
110
+ end
111
+
112
+ it "sets timestamps from the response metadata" do
113
+ model.create!
114
+
115
+ expect(model.created_at).to eq(DateTime.parse("2013-06-10 10:41:15 -0700"))
116
+ expect(model.updated_at).to eq(DateTime.parse("2015-06-10 10:41:15 -0700"))
117
+ end
118
+ end
119
+
120
+ describe "#update!" do
121
+ before do
122
+ allow(client.base).to receive(:put) {
123
+ {
124
+ :metadata => {
125
+ :guid => guid,
126
+ :created_at => "2013-06-10 10:41:15 -0700",
127
+ :updated_at => "2015-06-12 10:41:15 -0700"
128
+ },
129
+ :entity => {
130
+ :foo => "updated"
131
+ }
132
+ }
133
+ }
134
+ end
135
+
136
+ it "updates using the client with the v2 api, its plural model name, object guid, and diff object" do
137
+ model.foo = "bar"
138
+ expect(client.base).to receive(:put).with("v2", :test_models, guid,
139
+ :content => :json,
140
+ :accept => :json,
141
+ :payload => {:foo => "bar"}
142
+ )
143
+ model.update!
144
+ end
145
+
146
+ it "updates the updated_at timestamp" do
147
+ model.update!
148
+ expect(model.updated_at).to eq(DateTime.parse("2015-06-12 10:41:15 -0700"))
149
+ end
150
+
151
+ it "reloads it's data from the manifest" do
152
+ model.update!
153
+ expect(model.foo).to eq("updated")
154
+ end
155
+
156
+ it "clears diff" do
157
+ model.foo = "bar"
158
+
159
+ expect(model.diff).to be_present
160
+ model.update!
161
+ expect(model.diff).not_to be_present
162
+ end
163
+ end
164
+
165
+ describe "delete" do
166
+ it "uses #delete!" do
167
+ expect(model).to receive(:delete!).with({}) { true }
168
+ model.delete
169
+ end
170
+
171
+ it "passes options along to delete!" do
172
+ expect(model).to receive(:delete!).with(:recursive => true) { true }
173
+ model.delete(:recursive => true)
174
+ end
175
+
176
+ context "without errors" do
177
+ it "returns true" do
178
+ expect(model).to receive(:delete!).with({}) { true }
179
+ expect(model.delete).to eq(true)
180
+ end
181
+ end
182
+
183
+ context "with errors" do
184
+ before do
185
+ allow(model.class).to receive(:model_name) { ActiveModel::Name.new(model, nil, "abstract_model") }
186
+ allow(model).to receive(:delete!) { raise CFoundry::APIError.new("HELP") }
187
+ end
188
+
189
+ it "does not raise an exception" do
190
+ expect { model.delete }.to_not raise_error
191
+ end
192
+
193
+ it "returns false" do
194
+ expect(model.delete).to eq(false)
195
+ end
196
+
197
+ context "without model-specific errors" do
198
+ it "adds generic base error " do
199
+ model.delete
200
+ expect(model.errors.full_messages.first).to match(/cloud controller reported an error/i)
201
+ end
202
+ end
203
+
204
+ context "with model-specific errors" do
205
+ it "does not set the generic error on base" do
206
+ model.delete
207
+ expect(model.errors.size).to eq(1)
208
+ end
209
+ end
210
+ end
211
+ end
212
+
213
+ describe "#delete!" do
214
+ before { allow(client.base).to receive(:delete) }
215
+
216
+ context "without options" do
217
+ it "deletes using the client with the v2 api, its plural model name, object guid, and empty params hash" do
218
+ expect(client.base).to receive(:delete).with("v2", :test_models, guid, :params => {})
219
+ model.delete!
220
+ end
221
+ end
222
+
223
+ context "with options" do
224
+ it "sends delete with the object guid and options" do
225
+ options = {:excellent => "billandted"}
226
+ expect(client.base).to receive(:delete).with("v2", :test_models, guid, :params => options)
227
+
228
+ model.delete!(options)
229
+ end
230
+ end
231
+
232
+ it "clears its manifest metadata" do
233
+ expect(model.manifest).to have_key(:metadata)
234
+ model.delete!
235
+ expect(model.manifest).not_to have_key(:metadata)
236
+ end
237
+
238
+ it "clears the diff" do
239
+ model.foo = "bar"
240
+ expect(model.diff).to be_present
241
+ model.delete!
242
+ expect(model.diff).not_to be_present
243
+ end
244
+
245
+ it "delete me" do
246
+ begin
247
+ model.delete!
248
+ rescue => ex
249
+ expect(ex.message).not_to match(/\?/)
250
+ end
251
+ end
252
+ end
253
+
254
+ describe "#to_key" do
255
+ context "when persisted" do
256
+ it "returns an enumerable containing the guid" do
257
+ expect(model.to_key).to respond_to(:each)
258
+ expect(model.to_key.first).to eq(guid)
259
+ end
260
+ end
261
+
262
+ context "when not persisted" do
263
+ let(:guid) { nil }
264
+
265
+ it "returns nil" do
266
+ expect(model.to_key).to be_nil
267
+ end
268
+ end
269
+ end
270
+
271
+ describe "#to_param" do
272
+ context "when persisted" do
273
+ it "returns the guid as a string" do
274
+ expect(model.to_param).to be_a(String)
275
+ expect(model.to_param).to eq(guid)
276
+ end
277
+ end
278
+
279
+ context "when not persisted" do
280
+ let(:guid) { nil }
281
+
282
+ it "returns nil" do
283
+ expect(model.to_param).to be_nil
284
+ end
285
+ end
286
+ end
287
+
288
+ describe "#persisted?" do
289
+ context "on a new object" do
290
+ let(:guid) { nil }
291
+ it "returns false" do
292
+ expect(model).not_to be_persisted
293
+ end
294
+ end
295
+
296
+ context "on an object with a guid" do
297
+ it "returns false" do
298
+ expect(model).to be_persisted
299
+ end
300
+ end
301
+
302
+ context "on an object that has been deleted" do
303
+ before do
304
+ allow(client.base).to receive(:delete)
305
+ model.delete
306
+ end
307
+
308
+ it "returns false" do
309
+ expect(model).not_to be_persisted
310
+ end
311
+ end
312
+ end
313
+
314
+ describe "metadata" do
315
+ let(:new_object) { client.test_model }
316
+
317
+ context "when metadata are set" do
318
+ it "has timestamps" do
319
+ expect(new_object.created_at).to be_nil
320
+ expect(new_object.updated_at).to be_nil
321
+ end
322
+ end
323
+
324
+ context "when metadata are not defined" do
325
+ before do
326
+ allow(new_object).to receive(:manifest).with(nil)
327
+ end
328
+
329
+ it "returns nil for timestamps" do
330
+ expect(new_object.updated_at).to be_nil
331
+ expect(new_object.updated_at).to be_nil
332
+ end
333
+ end
334
+ end
335
+
336
+ describe "creating a new object" do
337
+ let(:new_object) { client.test_model }
338
+
339
+ describe "getting attributes" do
340
+ it "does not go to cloud controller" do
341
+ expect {
342
+ new_object.foo
343
+ }.to_not raise_error
344
+ end
345
+
346
+ it "remembers set values" do
347
+ new_object.foo = "bar"
348
+ expect(new_object.foo).to eq("bar")
349
+ end
350
+ end
351
+
352
+ describe "getting associations" do
353
+ describe "to_one associations" do
354
+ it "returns the an empty object of the association's type" do
355
+ expect(new_object.domain.guid).to be_nil
356
+ end
357
+ end
358
+ end
359
+ end
360
+
361
+ describe "first_page" do
362
+ before do
363
+ WebMock.stub_request(:get, /v2\/test_models/).to_return(:body => {
364
+ "prev_url" => nil,
365
+ "next_url" => next_url,
366
+ "resources" => [{:metadata => {:guid => '1234'}}]
367
+ }.to_json)
368
+ end
369
+
370
+ context "when there is a next page" do
371
+ let(:next_url) { "/v2/test_models?&page=2&results-per-page=50" }
372
+ before do
373
+ WebMock.stub_request(:get, /v2\/test_models/).to_return(:body => {
374
+ "prev_url" => nil,
375
+ "next_url" => "/v2/test_models?&page=2&results-per-page=50",
376
+ "resources" => [{:metadata => {:guid => '1234'}}]
377
+ }.to_json)
378
+ end
379
+
380
+ it "has next_page set to true" do
381
+ results = client.test_models_first_page
382
+ expect(results[:next_page]).to be_true
383
+ expect(results[:results].length).to eq(1)
384
+ expect(results[:results].first).to be_a TestModel
385
+ end
386
+ end
387
+
388
+ context "when there is no next page" do
389
+ let(:next_url) { nil }
390
+
391
+ it "has next_page set to false" do
392
+ results = client.test_models_first_page
393
+ expect(results[:next_page]).to be_false
394
+ end
395
+ end
396
+ end
397
+
398
+ describe '#for_each' do
399
+ before do
400
+ next_url = '/v2/test_models?page=2&q=timestamp%3E2012-11-01T12:00:00Z%3Btimestamp%3C2012-11-01T13:00:00Z&results-per-page=50'
401
+
402
+ WebMock.stub_request(:get, /v2\/test_models\?inline-relations-depth=1/).to_return(:body => {
403
+ 'prev_url' => nil,
404
+ 'next_url' => next_url,
405
+ 'resources' => [{:metadata => {:guid => '1'}}, {:metadata => {:guid => '2'}}]
406
+ }.to_json).times(1)
407
+
408
+ WebMock.stub_request(:get, /#{Regexp.escape(next_url)}/).to_return(:body => {
409
+ 'prev_url' => nil,
410
+ 'next_url' => nil,
411
+ 'resources' => [{:metadata => {:guid => '3'}}]
412
+ }.to_json).times(1)
413
+ end
414
+
415
+ it 'yields each page to the given the block' do
416
+ results = []
417
+ client.test_models_for_each do |test_model|
418
+ results << test_model
419
+ end
420
+ expect(results.map(&:guid)).to eq(%w{1 2 3})
421
+ expect(results.first).to be_a TestModel
422
+ end
423
+ end
424
+
425
+ describe "#create_endpoint_name" do
426
+ let(:default_model) { DefaultTestModel.new(guid, client, manifest) }
427
+
428
+ it "defaults to the plural object name" do
429
+ expect(default_model.create_endpoint_name).to eq(:default_test_models)
430
+ end
431
+ end
432
+ end
433
+ end
434
+ end
@@ -0,0 +1,135 @@
1
+ require "spec_helper"
2
+
3
+ module CFoundry
4
+ module V2
5
+ describe Organization do
6
+ let(:client) { build(:client) }
7
+ let(:organization) { build(:organization, :client => client) }
8
+
9
+ it_behaves_like "a summarizeable model" do
10
+ subject { organization }
11
+ let(:summary_attributes) { {:name => "fizzbuzz"} }
12
+ end
13
+
14
+ it "has quota_definition" do
15
+ quota = build(:quota_definition)
16
+ organization.quota_definition = quota
17
+ expect(organization.quota_definition).to eq(quota)
18
+ end
19
+
20
+ it "has billing_enabled" do
21
+ [true, false].each do |v|
22
+ organization.billing_enabled = v
23
+ expect(organization.billing_enabled).to eq(v)
24
+ end
25
+ end
26
+
27
+ describe "#delete_user_from_all_roles" do
28
+ let(:user) { build(:user) }
29
+ let(:organization) do
30
+ build(:organization, client: client, users: [user],
31
+ managers: [user], billing_managers: [user], auditors: [user])
32
+ end
33
+
34
+ let(:status) { 201 }
35
+
36
+ let(:delete_from_org_response) do
37
+ <<-json
38
+ {
39
+ "metadata": {
40
+ "guid": "24113d03-204b-4d23-b320-4127ee9c0006",
41
+ "url": "/v2/organizations/24113d03-204b-4d23-b320-4127ee9c0006",
42
+ "created_at": "2013-08-17T00:47:03+00:00",
43
+ "updated_at": "2013-08-17T00:47:04+00:00"
44
+ },
45
+ "entity": {
46
+ "name": "dsabeti-the-org",
47
+ "billing_enabled": false,
48
+ "quota_definition_guid": "b72b1acb-ff4f-468d-99c0-05cd91012b62",
49
+ "status": "active",
50
+ "quota_definition_url": "/v2/quota_definitions/b72b1acb-ff4f-468d-99c0-05cd91012b62",
51
+ "spaces_url": "/v2/organizations/24113d03-204b-4d23-b320-4127ee9c0006/spaces",
52
+ "domains_url": "/v2/organizations/24113d03-204b-4d23-b320-4127ee9c0006/domains",
53
+ "users_url": "/v2/organizations/24113d03-204b-4d23-b320-4127ee9c0006/users",
54
+ "managers_url": "/v2/organizations/24113d03-204b-4d23-b320-4127ee9c0006/managers",
55
+ "billing_managers_url": "/v2/organizations/24113d03-204b-4d23-b320-4127ee9c0006/billing_managers",
56
+ "auditors_url": "/v2/organizations/24113d03-204b-4d23-b320-4127ee9c0006/auditors",
57
+ "app_events_url": "/v2/organizations/24113d03-204b-4d23-b320-4127ee9c0006/app_events"
58
+ }
59
+ }
60
+ json
61
+ end
62
+
63
+ let(:delete_from_space_response) do
64
+ <<-json
65
+ {
66
+ "metadata": {
67
+ "guid": "6825e318-7a3f-4d50-a2a9-dd7088c95347",
68
+ "url": "/v2/spaces/6825e318-7a3f-4d50-a2a9-dd7088c95347",
69
+ "created_at": "2013-10-18T00:54:34+00:00",
70
+ "updated_at": null
71
+ },
72
+ "entity": {
73
+ "name": "asdf",
74
+ "organization_guid": "24113d03-204b-4d23-b320-4127ee9c0006",
75
+ "organization_url": "/v2/organizations/24113d03-204b-4d23-b320-4127ee9c0006",
76
+ "developers_url": "/v2/spaces/6825e318-7a3f-4d50-a2a9-dd7088c95347/developers",
77
+ "managers_url": "/v2/spaces/6825e318-7a3f-4d50-a2a9-dd7088c95347/managers",
78
+ "auditors_url": "/v2/spaces/6825e318-7a3f-4d50-a2a9-dd7088c95347/auditors",
79
+ "apps_url": "/v2/spaces/6825e318-7a3f-4d50-a2a9-dd7088c95347/apps",
80
+ "domains_url": "/v2/spaces/6825e318-7a3f-4d50-a2a9-dd7088c95347/domains",
81
+ "service_instances_url": "/v2/spaces/6825e318-7a3f-4d50-a2a9-dd7088c95347/service_instances",
82
+ "app_events_url": "/v2/spaces/6825e318-7a3f-4d50-a2a9-dd7088c95347/app_events",
83
+ "events_url": "/v2/spaces/6825e318-7a3f-4d50-a2a9-dd7088c95347/events"
84
+ }
85
+ }
86
+ json
87
+ end
88
+
89
+ let(:space1) do
90
+ build(:space, organization: organization,
91
+ developers: [user], auditors: [user], managers: [user])
92
+ end
93
+
94
+ let(:space2) do
95
+ build(:space, organization: organization,
96
+ developers: [user], auditors: [user], managers: [user])
97
+ end
98
+
99
+ before do
100
+ allow(organization).to receive(:spaces).and_return([space1, space2])
101
+
102
+ stub_request(:delete, "http://api.example.com/v2/organizations/#{organization.guid}/users/#{user.guid}").to_return(status: status, body: delete_from_org_response)
103
+ stub_request(:delete, "http://api.example.com/v2/organizations/#{organization.guid}/managers/#{user.guid}").to_return(status: status, body: delete_from_org_response)
104
+ stub_request(:delete, "http://api.example.com/v2/organizations/#{organization.guid}/billing_managers/#{user.guid}").to_return(status: status, body: delete_from_org_response)
105
+ stub_request(:delete, "http://api.example.com/v2/organizations/#{organization.guid}/auditors/#{user.guid}").to_return(status: status, body: delete_from_org_response)
106
+
107
+ stub_request(:delete, "http://api.example.com/v2/spaces/#{space1.guid}/developers/#{user.guid}").to_return(status: status, body: delete_from_space_response)
108
+ stub_request(:delete, "http://api.example.com/v2/spaces/#{space1.guid}/managers/#{user.guid}").to_return(status: status, body: delete_from_space_response)
109
+ stub_request(:delete, "http://api.example.com/v2/spaces/#{space1.guid}/auditors/#{user.guid}").to_return(status: status, body: delete_from_space_response)
110
+
111
+ stub_request(:delete, "http://api.example.com/v2/spaces/#{space2.guid}/developers/#{user.guid}").to_return(status: status, body: delete_from_space_response)
112
+ stub_request(:delete, "http://api.example.com/v2/spaces/#{space2.guid}/managers/#{user.guid}").to_return(status: status, body: delete_from_space_response)
113
+ stub_request(:delete, "http://api.example.com/v2/spaces/#{space2.guid}/auditors/#{user.guid}").to_return(status: status, body: delete_from_space_response)
114
+ end
115
+
116
+ it "removes the given user from all roles in the org and all its spaces" do
117
+ organization.delete_user_from_all_roles(user)
118
+
119
+ expect(WebMock).to have_requested(:delete, "http://api.example.com/v2/organizations/#{organization.guid}/users/#{user.guid}")
120
+ expect(WebMock).to have_requested(:delete, "http://api.example.com/v2/organizations/#{organization.guid}/managers/#{user.guid}")
121
+ expect(WebMock).to have_requested(:delete, "http://api.example.com/v2/organizations/#{organization.guid}/billing_managers/#{user.guid}")
122
+ expect(WebMock).to have_requested(:delete, "http://api.example.com/v2/organizations/#{organization.guid}/auditors/#{user.guid}")
123
+
124
+ expect(WebMock).to have_requested(:delete, "http://api.example.com/v2/spaces/#{space1.guid}/auditors/#{user.guid}")
125
+ expect(WebMock).to have_requested(:delete, "http://api.example.com/v2/spaces/#{space1.guid}/managers/#{user.guid}")
126
+ expect(WebMock).to have_requested(:delete, "http://api.example.com/v2/spaces/#{space1.guid}/developers/#{user.guid}")
127
+
128
+ expect(WebMock).to have_requested(:delete, "http://api.example.com/v2/spaces/#{space2.guid}/auditors/#{user.guid}")
129
+ expect(WebMock).to have_requested(:delete, "http://api.example.com/v2/spaces/#{space2.guid}/managers/#{user.guid}")
130
+ expect(WebMock).to have_requested(:delete, "http://api.example.com/v2/spaces/#{space2.guid}/developers/#{user.guid}")
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,50 @@
1
+ require "spec_helper"
2
+
3
+ module CFoundry
4
+ module V2
5
+ describe QuotaDefinition do
6
+ let(:quota_definition) { build(:quota_definition) }
7
+
8
+ it "has guid" do
9
+ quota_definition.guid = "quota-definition-1"
10
+ expect(quota_definition.guid).to eq("quota-definition-1")
11
+ end
12
+
13
+ it "has name" do
14
+ quota_definition.name = "name"
15
+ expect(quota_definition.name).to eq("name")
16
+ end
17
+
18
+ it "has non_basic_services_allowed" do
19
+ [true, false].each do |v|
20
+ quota_definition.non_basic_services_allowed = v
21
+ expect(quota_definition.non_basic_services_allowed).to eq(v)
22
+ end
23
+ end
24
+
25
+ it "has total_services" do
26
+ [0, 1].each do |v|
27
+ quota_definition.total_services = v
28
+ expect(quota_definition.total_services).to eq(v)
29
+ end
30
+ end
31
+
32
+ it "has total_services" do
33
+ [0, 1].each do |v|
34
+ quota_definition.total_services = v
35
+ expect(quota_definition.total_services).to eq(v)
36
+ end
37
+ end
38
+
39
+ describe "querying" do
40
+ let(:client) { build(:client) }
41
+
42
+ it "is queryable by name" do
43
+ expect(client).to receive(:quota_definitions).with({:query=>[:name, "quota-name"]}) {[]}
44
+
45
+ client.quota_definition_by_name("quota-name")
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: UTF-8
2
+ require "spec_helper"
3
+
4
+ module CFoundry
5
+ module V2
6
+ describe Route do
7
+ let(:route) { build(:route) }
8
+ subject { route }
9
+
10
+ describe "validations" do
11
+ it { should validate_presence_of(:domain) }
12
+ it { should validate_presence_of(:space) }
13
+
14
+ # http://tools.ietf.org/html/rfc1035
15
+ it "only allows host names according to RFC1035" do
16
+ message = "can only include a-z, 0-9 and -"
17
+
18
+ expect(route).to allow_value("a", "starts-with-letter", "includes-9-digits", "ends-with-letter",
19
+ "ends-with-digit-9", "can--have--consecutive---dashes", "allows-UPPERCASE-chars").for(:host)
20
+
21
+ ["-must-start-with-letter", "9must-start-with-letter", "must-not-end-with-dash-", "must-not-include-punctuation-chars-@\#$%^&*()",
22
+ "must-not-include-special-chars-ä", "must.not.include.dots"].each do |bad_value|
23
+ expect(route).not_to allow_value(bad_value).for(:host).with_message(message)
24
+ end
25
+
26
+ expect(route).to ensure_length_of(:host).is_at_most(63)
27
+ end
28
+ end
29
+
30
+ describe "errors" do
31
+ before do
32
+ allow(route).to receive(:create!) { raise CFoundry::RouteHostTaken.new("the host is taken", 210003) }
33
+ end
34
+
35
+ it "populates errors on host" do
36
+ route.create
37
+ expect(route.errors[:host].first).to match(/the host is taken/i)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end