new_cfoundry 4.8.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 (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