openshift-origin-console 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (291) hide show
  1. data/COPYRIGHT +1 -0
  2. data/Gemfile +21 -0
  3. data/LICENSE +203 -0
  4. data/README.md +123 -0
  5. data/Rakefile +44 -0
  6. data/app/assets/images/cartridge-edge.gif +0 -0
  7. data/app/assets/images/console/arrow-down.png +0 -0
  8. data/app/assets/images/console/console-sprite.png +0 -0
  9. data/app/assets/images/favicon-32.png +0 -0
  10. data/app/assets/images/loader-dark.gif +0 -0
  11. data/app/assets/images/loader.gif +0 -0
  12. data/app/assets/images/sprite-vert.png +0 -0
  13. data/app/assets/javascripts/console.js +10 -0
  14. data/app/assets/javascripts/console/form.js.coffee +51 -0
  15. data/app/assets/stylesheets/_alerts.scss +84 -0
  16. data/app/assets/stylesheets/_breadcrumbs.scss +31 -0
  17. data/app/assets/stylesheets/_buttons.scss +229 -0
  18. data/app/assets/stylesheets/_code.scss +86 -0
  19. data/app/assets/stylesheets/_custom.scss +207 -0
  20. data/app/assets/stylesheets/_footer.scss +54 -0
  21. data/app/assets/stylesheets/_forms.scss +710 -0
  22. data/app/assets/stylesheets/_grid.scss +28 -0
  23. data/app/assets/stylesheets/_input-prepend-append.scss +138 -0
  24. data/app/assets/stylesheets/_labels.scss +40 -0
  25. data/app/assets/stylesheets/_mixins.scss +76 -0
  26. data/app/assets/stylesheets/_override-variables.scss +1 -0
  27. data/app/assets/stylesheets/_responsive.scss +438 -0
  28. data/app/assets/stylesheets/_ribbon.scss +57 -0
  29. data/app/assets/stylesheets/_type.scss +306 -0
  30. data/app/assets/stylesheets/_utilities.scss +10 -0
  31. data/app/assets/stylesheets/_variables.scss +131 -0
  32. data/app/assets/stylesheets/common.css.scss +82 -0
  33. data/app/assets/stylesheets/console/_application.scss +194 -0
  34. data/app/assets/stylesheets/console/_base.scss +26 -0
  35. data/app/assets/stylesheets/console/_breadcrumbs.scss +32 -0
  36. data/app/assets/stylesheets/console/_buttons.scss +214 -0
  37. data/app/assets/stylesheets/console/_core.scss +1002 -0
  38. data/app/assets/stylesheets/console/_dropdowns.scss +63 -0
  39. data/app/assets/stylesheets/console/_help.scss +54 -0
  40. data/app/assets/stylesheets/console/_mixins.scss +11 -0
  41. data/app/assets/stylesheets/console/_navbar.scss +415 -0
  42. data/app/assets/stylesheets/console/_ribbon.scss +82 -0
  43. data/app/assets/stylesheets/console/_tile.scss +122 -0
  44. data/app/assets/stylesheets/origin.css.scss +37 -0
  45. data/app/controllers/account/dashboard.rb +13 -0
  46. data/app/controllers/account_controller.rb +3 -0
  47. data/app/controllers/application_types_controller.rb +80 -0
  48. data/app/controllers/applications_controller.rb +183 -0
  49. data/app/controllers/building_controller.rb +81 -0
  50. data/app/controllers/capability_aware.rb +18 -0
  51. data/app/controllers/cartridge_types_controller.rb +53 -0
  52. data/app/controllers/cartridges_controller.rb +43 -0
  53. data/app/controllers/console/auth/basic.rb +65 -0
  54. data/app/controllers/console/auth/none.rb +5 -0
  55. data/app/controllers/console/auth/remote_user.rb +69 -0
  56. data/app/controllers/console/rescue.rb +48 -0
  57. data/app/controllers/console_controller.rb +19 -0
  58. data/app/controllers/console_index_controller.rb +14 -0
  59. data/app/controllers/domain_aware.rb +26 -0
  60. data/app/controllers/domain_session_sweeper.rb +29 -0
  61. data/app/controllers/domains_controller.rb +30 -0
  62. data/app/controllers/keys_controller.rb +43 -0
  63. data/app/controllers/scaling_controller.rb +46 -0
  64. data/app/controllers/sshkey_aware.rb +23 -0
  65. data/app/controllers/sshkey_session_sweeper.rb +29 -0
  66. data/app/controllers/user_session_sweeper.rb +29 -0
  67. data/app/helpers/console/community_helper.rb +78 -0
  68. data/app/helpers/console/console_helper.rb +26 -0
  69. data/app/helpers/console/help_helper.rb +270 -0
  70. data/app/helpers/console/html5_boilerplate_helper.rb +63 -0
  71. data/app/helpers/console/layout_helper.rb +277 -0
  72. data/app/helpers/console/model_helper.rb +106 -0
  73. data/app/helpers/console/secured_helper.rb +5 -0
  74. data/app/models/alias.rb +10 -0
  75. data/app/models/application.rb +148 -0
  76. data/app/models/application_associations.rb +36 -0
  77. data/app/models/application_template.rb +90 -0
  78. data/app/models/application_type.rb +258 -0
  79. data/app/models/async_aware.rb +60 -0
  80. data/app/models/capabilities.rb +62 -0
  81. data/app/models/cartridge.rb +122 -0
  82. data/app/models/cartridge_type.rb +140 -0
  83. data/app/models/domain.rb +44 -0
  84. data/app/models/domain_associations.rb +33 -0
  85. data/app/models/embedded.rb +11 -0
  86. data/app/models/gear.rb +13 -0
  87. data/app/models/gear_group.rb +104 -0
  88. data/app/models/key.rb +87 -0
  89. data/app/models/quickstart.rb +135 -0
  90. data/app/models/rest_api.rb +130 -0
  91. data/app/models/rest_api/base.rb +781 -0
  92. data/app/models/rest_api/cacheable.rb +91 -0
  93. data/app/models/rest_api/environment.rb +13 -0
  94. data/app/models/rest_api/info.rb +34 -0
  95. data/app/models/rest_api/log_subscriber.rb +29 -0
  96. data/app/models/rest_api/railties/controller_runtime.rb +37 -0
  97. data/app/models/user.rb +27 -0
  98. data/app/models/user_associations.rb +6 -0
  99. data/app/views/account/_domain.html.haml +14 -0
  100. data/app/views/account/_keys.html.haml +20 -0
  101. data/app/views/account/_user.html.haml +5 -0
  102. data/app/views/account/show.html.haml +15 -0
  103. data/app/views/application_templates/_application_template.html.haml +5 -0
  104. data/app/views/application_types/_application_type.html.haml +19 -0
  105. data/app/views/application_types/_custom.html.haml +19 -0
  106. data/app/views/application_types/_persisted.html.haml +26 -0
  107. data/app/views/application_types/_tile.html.haml +9 -0
  108. data/app/views/application_types/index.html.haml +87 -0
  109. data/app/views/application_types/search.html.haml +67 -0
  110. data/app/views/application_types/show.html.haml +219 -0
  111. data/app/views/applications/_application.html.haml +34 -0
  112. data/app/views/applications/_applications_filter.html.haml +8 -0
  113. data/app/views/applications/_footer.html.haml +0 -0
  114. data/app/views/applications/_name.html.haml +28 -0
  115. data/app/views/applications/delete.html.haml +19 -0
  116. data/app/views/applications/get_started.html.haml +145 -0
  117. data/app/views/applications/index.html.haml +55 -0
  118. data/app/views/applications/show.html.haml +193 -0
  119. data/app/views/building/delete.html.haml +22 -0
  120. data/app/views/building/new.html.haml +57 -0
  121. data/app/views/building/show.html.haml +12 -0
  122. data/app/views/cartridge_types/_cartridge_type.html.haml +61 -0
  123. data/app/views/cartridge_types/index.html.haml +37 -0
  124. data/app/views/cartridge_types/show.html.haml +21 -0
  125. data/app/views/cartridges/next_steps.html.haml +58 -0
  126. data/app/views/cartridges/show.html.haml +1 -0
  127. data/app/views/console/error.html.haml +58 -0
  128. data/app/views/console/help.html.haml +90 -0
  129. data/app/views/console/not_found.html.haml +69 -0
  130. data/app/views/console/unauthorized.html.haml +7 -0
  131. data/app/views/domains/_domain.html.haml +14 -0
  132. data/app/views/domains/_form.html.haml +13 -0
  133. data/app/views/domains/edit.html.haml +5 -0
  134. data/app/views/domains/new.html.haml +6 -0
  135. data/app/views/keys/_form.html.haml +14 -0
  136. data/app/views/keys/_simple_form.html.haml +14 -0
  137. data/app/views/keys/new.html.haml +2 -0
  138. data/app/views/layouts/_footer.html.haml +38 -0
  139. data/app/views/layouts/_head.html.haml +35 -0
  140. data/app/views/layouts/console.html.haml +60 -0
  141. data/app/views/layouts/console/_header.html.haml +44 -0
  142. data/app/views/layouts/console/_identity.html.haml +7 -0
  143. data/app/views/layouts/console/_javascripts.html.haml +5 -0
  144. data/app/views/layouts/console/_stylesheets.html.haml +6 -0
  145. data/app/views/scaling/delete.html.haml +17 -0
  146. data/app/views/scaling/new.html.haml +24 -0
  147. data/app/views/scaling/show.html.haml +81 -0
  148. data/app/views/shared/_tracking.html.haml +0 -0
  149. data/conf/console.conf.example +108 -0
  150. data/conf/openshift_console.conf +10 -0
  151. data/config/cartridge_types.yml +54 -0
  152. data/config/initializers/barista_config.rb +86 -0
  153. data/config/initializers/cartridge_types.rb +5 -0
  154. data/config/initializers/console_security.rb +1 -0
  155. data/config/initializers/date_helper.rb +5 -0
  156. data/config/initializers/extended_logger.rb +51 -0
  157. data/config/initializers/formtastic.rb +100 -0
  158. data/config/initializers/inflections.rb +38 -0
  159. data/config/initializers/rdiscount.rb +8 -0
  160. data/config/initializers/rest_api.rb +22 -0
  161. data/config/initializers/sass.rb +30 -0
  162. data/config/initializers/session_trace.rb +32 -0
  163. data/config/initializers/x_frame_options.rb +53 -0
  164. data/config/locales/en.yml +12 -0
  165. data/lib/active_resource/associations.rb +107 -0
  166. data/lib/active_resource/associations/builder/association.rb +35 -0
  167. data/lib/active_resource/associations/builder/belongs_to.rb +5 -0
  168. data/lib/active_resource/associations/builder/has_many.rb +5 -0
  169. data/lib/active_resource/associations/builder/has_one.rb +5 -0
  170. data/lib/active_resource/persistent_connection.rb +341 -0
  171. data/lib/active_resource/persistent_http_mock.rb +68 -0
  172. data/lib/active_resource/reflection.rb +78 -0
  173. data/lib/console.rb +8 -0
  174. data/lib/console/config_file.rb +13 -0
  175. data/lib/console/configuration.rb +163 -0
  176. data/lib/console/engine.rb +28 -0
  177. data/lib/console/formtastic/bootstrap_form_builder.rb +369 -0
  178. data/lib/console/rails/app_redirector.rb +40 -0
  179. data/lib/console/rails/filter_hash.rb +15 -0
  180. data/lib/console/rails/routes.rb +51 -0
  181. data/lib/console/version.rb +5 -0
  182. data/lib/tasks/assets.rake +79 -0
  183. data/lib/tasks/stats.rake +18 -0
  184. data/lib/tasks/test_suites.rake +73 -0
  185. data/test/coverage_helper.rb +27 -0
  186. data/test/fixtures/cartridges.json +1 -0
  187. data/test/fixtures/quickstarts.csv +3 -0
  188. data/test/functional/account_controller_test.rb +14 -0
  189. data/test/functional/application_types_controller_test.rb +251 -0
  190. data/test/functional/applications_controller_sanity_test.rb +26 -0
  191. data/test/functional/applications_controller_test.rb +365 -0
  192. data/test/functional/building_controller_test.rb +203 -0
  193. data/test/functional/cartridge_types_controller_isolation_test.rb +68 -0
  194. data/test/functional/cartridge_types_controller_test.rb +48 -0
  195. data/test/functional/cartridges_controller_test.rb +83 -0
  196. data/test/functional/console_auth_basic_controller_test.rb +82 -0
  197. data/test/functional/console_auth_remote_user_controller_test.rb +90 -0
  198. data/test/functional/console_index_controller_test.rb +22 -0
  199. data/test/functional/domains_controller_test.rb +194 -0
  200. data/test/functional/keys_controller_test.rb +163 -0
  201. data/test/functional/quickstarts.json +18 -0
  202. data/test/functional/scaling_controller_test.rb +153 -0
  203. data/test/integration/assets_test.rb +34 -0
  204. data/test/integration/help_link_test.rb +43 -0
  205. data/test/integration/quickstarts_test.rb +24 -0
  206. data/test/integration/rescue_from_test.rb +25 -0
  207. data/test/integration/rest_api/application_test.rb +115 -0
  208. data/test/integration/rest_api/cartridge_test.rb +44 -0
  209. data/test/integration/rest_api/cartridge_type_test.rb +143 -0
  210. data/test/integration/rest_api/domain_test.rb +91 -0
  211. data/test/integration/rest_api/info_test.rb +9 -0
  212. data/test/integration/rest_api/key_test.rb +85 -0
  213. data/test/integration/static_pages_test.rb +44 -0
  214. data/test/rails_app/Rakefile +7 -0
  215. data/test/rails_app/app/controllers/application_controller.rb +5 -0
  216. data/test/rails_app/config.ru +4 -0
  217. data/test/rails_app/config/application.rb +48 -0
  218. data/test/rails_app/config/boot.rb +10 -0
  219. data/test/rails_app/config/database.yml +25 -0
  220. data/test/rails_app/config/environment.rb +5 -0
  221. data/test/rails_app/config/environments/development.rb +38 -0
  222. data/test/rails_app/config/environments/production.rb +70 -0
  223. data/test/rails_app/config/environments/test.rb +43 -0
  224. data/test/rails_app/config/initializers/auth.rb +0 -0
  225. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  226. data/test/rails_app/config/initializers/inflections.rb +10 -0
  227. data/test/rails_app/config/initializers/mime_types.rb +5 -0
  228. data/test/rails_app/config/initializers/secret_token.rb +7 -0
  229. data/test/rails_app/config/initializers/session_store.rb +8 -0
  230. data/test/rails_app/config/locales/en.yml +5 -0
  231. data/test/rails_app/config/routes.rb +4 -0
  232. data/test/rails_app/script/rails +6 -0
  233. data/test/support/auth.rb +111 -0
  234. data/test/support/base.rb +142 -0
  235. data/test/support/errors.rb +28 -0
  236. data/test/support/rest_api.rb +189 -0
  237. data/test/test_helper.rb +14 -0
  238. data/test/unit/active_model_compliance_test.rb +23 -0
  239. data/test/unit/async_aware_test.rb +55 -0
  240. data/test/unit/configuration_test.rb +158 -0
  241. data/test/unit/filter_hash_test.rb +64 -0
  242. data/test/unit/helpers/model_helper_test.rb +61 -0
  243. data/test/unit/overrides_test.rb +9 -0
  244. data/test/unit/rest_api_test.rb +1590 -0
  245. data/vendor/assets/javascripts/MIT-LICENSE.txt +20 -0
  246. data/vendor/assets/javascripts/bootstrap-collapse.js +157 -0
  247. data/vendor/assets/javascripts/bootstrap-dropdown.js +100 -0
  248. data/vendor/assets/javascripts/bootstrap-tab.js +135 -0
  249. data/vendor/assets/javascripts/bootstrap-transition.js +61 -0
  250. data/vendor/assets/javascripts/jquery.spin.js +47 -0
  251. data/vendor/assets/javascripts/jquery.ui.widget.js +16 -0
  252. data/vendor/assets/javascripts/jquery_cookie.js +41 -0
  253. data/vendor/assets/javascripts/jquery_validate_min.js +51 -0
  254. data/vendor/assets/javascripts/modernizr.min.js +2 -0
  255. data/vendor/assets/javascripts/plugins.js +16 -0
  256. data/vendor/assets/stylesheets/bootstrap/_accordion.scss +28 -0
  257. data/vendor/assets/stylesheets/bootstrap/_alerts.scss +70 -0
  258. data/vendor/assets/stylesheets/bootstrap/_breadcrumbs.scss +22 -0
  259. data/vendor/assets/stylesheets/bootstrap/_button-groups.scss +147 -0
  260. data/vendor/assets/stylesheets/bootstrap/_buttons.scss +183 -0
  261. data/vendor/assets/stylesheets/bootstrap/_carousel.scss +121 -0
  262. data/vendor/assets/stylesheets/bootstrap/_close.scss +18 -0
  263. data/vendor/assets/stylesheets/bootstrap/_code.scss +57 -0
  264. data/vendor/assets/stylesheets/bootstrap/_component-animations.scss +18 -0
  265. data/vendor/assets/stylesheets/bootstrap/_dropdowns.scss +130 -0
  266. data/vendor/assets/stylesheets/bootstrap/_forms.scss +522 -0
  267. data/vendor/assets/stylesheets/bootstrap/_grid.scss +8 -0
  268. data/vendor/assets/stylesheets/bootstrap/_hero-unit.scss +20 -0
  269. data/vendor/assets/stylesheets/bootstrap/_labels.scss +32 -0
  270. data/vendor/assets/stylesheets/bootstrap/_layouts.scss +17 -0
  271. data/vendor/assets/stylesheets/bootstrap/_mixins.scss +602 -0
  272. data/vendor/assets/stylesheets/bootstrap/_modals.scss +84 -0
  273. data/vendor/assets/stylesheets/bootstrap/_navbar.scss +299 -0
  274. data/vendor/assets/stylesheets/bootstrap/_navs.scss +353 -0
  275. data/vendor/assets/stylesheets/bootstrap/_pager.scss +30 -0
  276. data/vendor/assets/stylesheets/bootstrap/_pagination.scss +55 -0
  277. data/vendor/assets/stylesheets/bootstrap/_popovers.scss +49 -0
  278. data/vendor/assets/stylesheets/bootstrap/_progress-bars.scss +95 -0
  279. data/vendor/assets/stylesheets/bootstrap/_reset.scss +126 -0
  280. data/vendor/assets/stylesheets/bootstrap/_scaffolding.scss +33 -0
  281. data/vendor/assets/stylesheets/bootstrap/_sprites.scss +158 -0
  282. data/vendor/assets/stylesheets/bootstrap/_tables.scss +150 -0
  283. data/vendor/assets/stylesheets/bootstrap/_thumbnails.scss +35 -0
  284. data/vendor/assets/stylesheets/bootstrap/_tooltip.scss +35 -0
  285. data/vendor/assets/stylesheets/bootstrap/_type.scss +218 -0
  286. data/vendor/assets/stylesheets/bootstrap/_utilities.scss +23 -0
  287. data/vendor/assets/stylesheets/bootstrap/_variables.scss +107 -0
  288. data/vendor/assets/stylesheets/bootstrap/_wells.scss +17 -0
  289. data/vendor/assets/stylesheets/bootstrap/bootstrap.scss +66 -0
  290. data/vendor/assets/stylesheets/bootstrap/responsive.scss +334 -0
  291. metadata +506 -0
@@ -0,0 +1,158 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ #
4
+ # Mock tests only - should verify functionality of ActiveResource extensions
5
+ # and simple server/client interactions via HttpMock
6
+ #
7
+ class ConfigurationTest < ActiveSupport::TestCase
8
+ setup do
9
+ @old_config = Console.instance_variable_get(:@config)
10
+ Console.instance_variable_set(:@config, nil)
11
+ end
12
+ teardown{ Console.instance_variable_set(:@config, @old_config) }
13
+
14
+ def expects_file_read(contents, file='file')
15
+ IO.expects(:read).with(File.expand_path(file)).returns(contents)
16
+ end
17
+
18
+ test 'ConfigFile handles key pairs' do
19
+ expects_file_read(<<-FILE.strip_heredoc)
20
+ key=1
21
+ escaped\\==2
22
+ double_escaped\\\\=3
23
+ escaped_value=\\4
24
+ spaces = 5
25
+ #comment=6
26
+
27
+ commented_value=7 # some comments
28
+ comm#ented_key=8
29
+ greedy=equals=9
30
+ FILE
31
+ c = Console::ConfigFile.new('file')
32
+ assert_equal({
33
+ 'key' => '1',
34
+ 'escaped=' => '2',
35
+ 'double_escaped\\' => '3',
36
+ 'escaped_value' => '4',
37
+ 'spaces' => '5',
38
+ 'commented_value' => '7',
39
+ 'greedy' => 'equals=9',
40
+ }, c)
41
+ end
42
+
43
+ test 'Console.configure yields' do
44
+ Console.configure{ @ran = true }
45
+ assert @ran
46
+ end
47
+
48
+ test 'get default user agent' do
49
+ assert Console.config.user_agent =~ /openshift_console.*?\d+\.\d+\.\d/
50
+ end
51
+
52
+ test 'Console.configure reads file' do
53
+ expects_file_read(<<-FILE.strip_heredoc)
54
+ BROKER_URL=foo
55
+ BROKER_API_USER=bob
56
+ FILE
57
+ Console.configure('file')
58
+ assert_equal 'foo', Console.config.api[:url]
59
+ assert_equal 'bob', Console.config.api[:user]
60
+ assert_equal 'file', Console.config.api[:source]
61
+ assert_nil Console.config.security_controller # base config object has no defaults
62
+ end
63
+
64
+ test 'Console.configure default succeeds' do
65
+ Console.configure(File.expand_path('../../../conf/console.conf.example', __FILE__))
66
+ end
67
+
68
+ test 'Console.configure raises IO errors' do
69
+ IO.expects(:read).with(File.expand_path('file')).raises(Errno::ENOENT)
70
+ assert_raise(Errno::ENOENT){ Console.configure('file') }
71
+ end
72
+
73
+ test 'Console.configure raises InvalidConfiguration' do
74
+ expects_file_read(<<-FILE.strip_heredoc)
75
+ FILE
76
+ assert_raise(Console::InvalidConfiguration){ Console.configure('file') }
77
+ end
78
+
79
+ test 'Console.configure sets security_controller from basic' do
80
+ expects_file_read(<<-FILE.strip_heredoc)
81
+ BROKER_URL=foo
82
+ CONSOLE_SECURITY=basic
83
+ FILE
84
+ Console.configure('file')
85
+ assert_equal Console::Auth::Basic, Console.config.security_controller.constantize
86
+ end
87
+
88
+ test 'Console.configure sets security_controller from remote_user' do
89
+ expects_file_read(<<-FILE.strip_heredoc)
90
+ BROKER_URL=foo
91
+ CONSOLE_SECURITY=remote_user
92
+ REMOTE_USER_HEADER=X-Remote-User
93
+ REMOTE_USER_NAME_HEADER=X-Remote-User-Name
94
+ REMOTE_USER_COPY_HEADERS=X-Remote-User,Cookies
95
+ FILE
96
+ Console.configure('file')
97
+ assert_equal Console::Auth::RemoteUser, Console.config.security_controller.constantize
98
+ assert_equal ['X-Remote-User','Cookies'], Console.config.remote_user_copy_headers
99
+ assert_equal 'X-Remote-User', Console.config.remote_user_header
100
+ assert_equal 'X-Remote-User-Name', Console.config.remote_user_name_header
101
+ end
102
+
103
+ test 'Console.configure sets security_controller to arbitrary' do
104
+ expects_file_read(<<-FILE.strip_heredoc)
105
+ BROKER_URL=foo
106
+ CONSOLE_SECURITY=Console::Auth::None
107
+ FILE
108
+ Console.configure('file')
109
+ assert_equal Console::Auth::None, Console.config.security_controller.constantize
110
+ end
111
+
112
+ test 'Console.config.api sets api :external' do
113
+ expects_file_read(<<-FILE.strip_heredoc, '~/.openshift/console.conf')
114
+ BROKER_URL=foo
115
+ BROKER_API_SOURCE=ignored
116
+ BROKER_API_USER=bob
117
+ BROKER_API_SYMBOL=:foo
118
+ BROKER_API_TIMEOUT=0
119
+ BROKER_API_SSL_OPTIONS={:verify_mode => OpenSSL::SSL::VERIFY_NONE}
120
+ BROKER_PROXY_URL=proxy
121
+ CONSOLE_SECURITY=Console::Auth::None
122
+ FILE
123
+ (config = Console::Configuration.new).api = :external
124
+ assert_equal 'foo', config.api[:url]
125
+ assert_equal 'proxy', config.api[:proxy]
126
+ assert_equal 'bob', config.api[:user]
127
+ assert_equal :foo, config.api[:symbol]
128
+ assert_equal 0, config.api[:timeout]
129
+ assert_equal '~/.openshift/console.conf', config.api[:source]
130
+ assert_equal({'verify_mode' => OpenSSL::SSL::VERIFY_NONE}, config.api[:ssl_options])
131
+ assert_equal OpenSSL::SSL::VERIFY_NONE, config.api[:ssl_options][:verify_mode]
132
+ assert_nil config.security_controller # is ignored
133
+ end
134
+
135
+ test 'Console.config.api accepts :local' do
136
+ (config = Console::Configuration.new).api = :local
137
+ assert_equal 'https://localhost/broker/rest', config.api[:url]
138
+ assert_equal :local, config.api[:source]
139
+ assert_nil config.security_controller # is ignored
140
+ end
141
+
142
+ test 'Console.config.api accepts valid object' do
143
+ (config = Console::Configuration.new).api = {:url => 'foo', :user => 'bob'}
144
+ assert_equal 'foo', config.api[:url]
145
+ assert_equal 'bob', config.api[:user]
146
+ assert_equal 'object in config', config.api[:source]
147
+ assert_nil config.security_controller # is ignored
148
+ end
149
+
150
+ test 'Console.config.api raises on invalid object' do
151
+ assert_raise(Console::InvalidConfiguration){ Console::Configuration.new.api = {:url => nil, :user => 'bob'} }
152
+ end
153
+
154
+ test 'Console.config.api raises on unrecognized option' do
155
+ assert_raise(Console::InvalidConfiguration){ Console::Configuration.new.api = nil }
156
+ end
157
+ end
158
+
@@ -0,0 +1,64 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class FilterHashTest < ActiveSupport::TestCase
4
+
5
+ F = '[FILTERED]'
6
+
7
+ def test_filters
8
+ assert_equal ['password'], FilterHash.send(:filters)
9
+ end
10
+
11
+ def test_filter_defaults
12
+ keys = [:password, 'password', 'Password', 'old_password', 'password_confirmation']
13
+ assert_equal filtered_hash(keys), FilterHash.safe_values(valid_hash(keys))
14
+ end
15
+
16
+ def test_filters_are_cached
17
+ FilterHash.instance_variable_set(:@filters, nil)
18
+ FilterHash.safe_values({})
19
+ assert first = FilterHash.instance_variable_get(:@filters)
20
+ FilterHash.safe_values({})
21
+ assert_equal first, FilterHash.instance_variable_get(:@filters)
22
+
23
+ end
24
+
25
+
26
+ def test_filter_case_partials
27
+ FilterHash.expects(:filters).returns(['case'])
28
+ keys = [:case, 'Case', 'cAse', 'lowerCase', 'lowercase']
29
+ assert_equal filtered_hash(keys), FilterHash.safe_values(valid_hash(keys))
30
+ end
31
+
32
+ def test_filter_case_nomatch
33
+ FilterHash.expects(:filters).returns(['case'])
34
+ keys = [:cas, 'cas', 'Cas', 'caS', 'ase']
35
+ assert_equal valid_hash(keys), FilterHash.safe_values(valid_hash(keys))
36
+ end
37
+
38
+ def test_filter_case_multiple
39
+ FilterHash.expects(:filters).returns(['password', 'other'])
40
+ keys = [:password, :passWord, :other, :otheR, 'other', 'password', 'Password', 'oTher']
41
+ assert_equal filtered_hash(keys), FilterHash.safe_values(valid_hash(keys))
42
+ end
43
+
44
+ def test_filter_case_multiple_nomatch
45
+ FilterHash.expects(:filters).returns(['foo', 'bar'])
46
+ keys = [:password, :passWord, :other, :otheR, 'other', 'password', 'Password', 'oTher']
47
+ assert_equal valid_hash(keys), FilterHash.safe_values(valid_hash(keys))
48
+ end
49
+
50
+ def valid_hash(*args)
51
+ h = {}
52
+ args.each{ |k| h[k] = 'test' }
53
+ h
54
+ end
55
+ def filtered_hash(*args)
56
+ h = {}
57
+ args.each{ |k| h[k] = F }
58
+ h
59
+ end
60
+
61
+ def assert_filtered(hash, *args)
62
+ args.each{ |k| assert_equal '[FILTERED]', hash[k], "Key #{k} was not filtered" }
63
+ end
64
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+
4
+ class Console::ModelHelperTest < ActionView::TestCase
5
+
6
+ def test_gear_group_states
7
+ assert_equal 'Started', gear_group_states([:started])
8
+ assert_equal 'Stopped', gear_group_states([:stopped])
9
+ assert_equal 'Unknown', gear_group_states([:unknown])
10
+ assert_equal 'Foo', gear_group_states([:foo])
11
+ assert_equal 'Unknown', gear_group_states([:unknown, :unknown])
12
+ assert_equal '0/2 started', gear_group_states([:unknown, :stopped])
13
+ assert_equal '1/2 started', gear_group_states([:started, :stopped])
14
+ assert_equal 'Started', gear_group_states([:started, :started])
15
+ end
16
+
17
+ def test_gear_group_count
18
+ s = Gear.new(:gear_profile => :small)
19
+ m = Gear.new(:gear_profile => :medium)
20
+ l = Gear.new(:gear_profile => :large)
21
+ t = Gear.new(:gear_profile => :tiny)
22
+ assert_equal '1 small', gear_group_count([s])
23
+ assert_equal '1 medium and 1 small', gear_group_count([s, m])
24
+ assert_equal '1 large, 1 medium, and 1 small', gear_group_count([s, m, l])
25
+ assert_equal '2 large', gear_group_count([l,l])
26
+ assert_equal 'None', gear_group_count([])
27
+ end
28
+
29
+ def test_web_cartridge_scale_title
30
+ assert /maximum amount/i =~ web_cartridge_scale_title(stub(:current_scale => 2, :scales_from => 1, :scales_to => 2))
31
+ assert /minimum amount/i =~ web_cartridge_scale_title(stub(:current_scale => 1, :scales_from => 1, :scales_to => 2))
32
+ assert /multiple copies/i =~ web_cartridge_scale_title(stub(:current_scale => 2, :scales_from => 1, :scales_to => 3))
33
+ end
34
+
35
+ def test_scale_from_options
36
+ assert_equal({
37
+ :as => :select,
38
+ :collection => [['1',1],['2',2],['3',3]],
39
+ :include_blank => false,
40
+ },
41
+ scale_from_options(stub(:supported_scales_from => 1, :supported_scales_to => -1), 3))
42
+ assert_equal({
43
+ :as => :string
44
+ },
45
+ scale_from_options(stub(:supported_scales_from => 1, :supported_scales_to => -1), 6, 5))
46
+ end
47
+
48
+ def test_scale_to_options
49
+ assert_equal({
50
+ :as => :select,
51
+ :collection => [['1',1],['2',2],['3',3],['All available', -1]],
52
+ :include_blank => false,
53
+ },
54
+ scale_to_options(stub(:supported_scales_from => 1, :supported_scales_to => -1), 3))
55
+ assert_equal({
56
+ :as => :string,
57
+ :hint => 'Use -1 to scale to your current account limits',
58
+ },
59
+ scale_to_options(stub(:supported_scales_from => 1, :supported_scales_to => -1), 6, 5))
60
+ end
61
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class OverridesTest < ActiveSupport::TestCase
4
+
5
+ test "rack response override" do
6
+ r = ActionDispatch::Response.new
7
+ assert 'SAMEORIGIN', r.to_a[1]['X-Frame-Options']
8
+ end
9
+ end
@@ -0,0 +1,1590 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ #
4
+ # Mock tests only - should verify functionality of ActiveResource extensions
5
+ # and simple server/client interactions via HttpMock
6
+ #
7
+ class RestApiTest < ActiveSupport::TestCase
8
+
9
+ uses_http_mock
10
+ setup{ Rails.cache.clear }
11
+
12
+ def setup
13
+ ActiveResource::HttpMock.reset!
14
+
15
+ RestApi.instance_variable_set('@info', nil)
16
+
17
+ @ts = "#{Time.now.to_i}#{gen_small_uuid[0,6]}"
18
+
19
+ @user = RestApi::Authorization.new 'test1', '1234'
20
+ @auth_headers = {'Cookie' => "rh_sso=1234", 'Authorization' => 'Basic dGVzdDE6'};
21
+
22
+ ActiveSupport::XmlMini.backend = 'REXML'
23
+ end
24
+
25
+ def mock
26
+ ActiveResource::HttpMock.respond_to do |mock|
27
+ mock.get '/broker/rest/user/keys.json', {'Accept' => 'application/json'}.merge!(@auth_headers), [{:type => :rsa, :name => 'test1', :value => '1234' }].to_json()
28
+ mock.post '/broker/user/keys.json', {'Content-Type' => 'application/json'}.merge!(@auth_headers), {:type => :rsa, :name => 'test2', :value => '1234_2' }.to_json()
29
+ mock.delete '/user/keys/test1.json', {'Accept' => 'application/json'}.merge!(@auth_headers), {}
30
+ mock.get '/user.json', {'Accept' => 'application/json'}.merge!(@auth_headers), { :login => 'test1' }.to_json()
31
+ mock.get '/domains.json', {'Accept' => 'application/json'}.merge!(@auth_headers), [{ :name => 'adomain' }].to_json()
32
+ mock.get '/domains/adomain/applications.json', {'Accept' => 'application/json'}.merge!(@auth_headers), [{ :name => 'app1' }, { :name => 'app2' }].to_json()
33
+ end
34
+ end
35
+
36
+ class AnonymousApi < RestApi::Base
37
+ allow_anonymous
38
+ end
39
+ class ProtectedApi < RestApi::Base
40
+ end
41
+
42
+ def test_anonymous_api
43
+ assert AnonymousApi.allow_anonymous?
44
+ assert AnonymousApi.connection
45
+ end
46
+
47
+ def test_protected_api
48
+ assert !ProtectedApi.allow_anonymous?
49
+ assert_raises RestApi::MissingAuthorizationError do
50
+ ProtectedApi.connection
51
+ end
52
+ assert ProtectedApi.connection :as => Test::WebUser.new
53
+ end
54
+
55
+ def test_base_connection
56
+ base = RestApi::Base.new :as => @user
57
+ connection = base.send('connection')
58
+ assert connection
59
+ assert_equal connection, base.send('connection') #second request preserves connection
60
+ assert_not_equal connection, base.send('connection', true) #forced refresh creates new connection
61
+ end
62
+
63
+ def test_agnostic_connection
64
+ assert_raise RestApi::MissingAuthorizationError do
65
+ RestApi::Base.connection
66
+ end
67
+ assert RestApi::Base.connection({:as => {}}).is_a? RestApi::UserAwareConnection
68
+ end
69
+
70
+ def test_translate_api_error
71
+ (errors = mock).expects(:add).once.with(:base, 'test')
72
+ RestApi::Base.translate_api_error(errors, nil, nil, 'test')
73
+ (errors = mock).expects(:add).once.with(:test, 'test')
74
+ RestApi::Base.translate_api_error(errors, nil, :test, 'test')
75
+ (errors = mock).expects(:add).once.with(:test, 'test')
76
+ RestApi::Base.translate_api_error(errors, nil, 'test', 'test')
77
+ (errors = mock).expects(:add).once.with(:test, I18n.t('116', :scope => [:rest_api, :errors]))
78
+ RestApi::Base.translate_api_error(errors, '116', 'test', 'test')
79
+ (errors = mock).expects(:add).once.with(:base, I18n.t('116', :scope => [:rest_api, :errors]))
80
+ RestApi::Base.translate_api_error(errors, '116', nil, nil)
81
+ end
82
+
83
+ def test_has_exit_code
84
+ a = RestApi::Base.new
85
+ a.errors.instance_variable_set(:@codes, {:a => [1]})
86
+ assert a.has_exit_code? 1
87
+ assert a.has_exit_code? 1, :on => 'a'
88
+ assert a.has_exit_code? 1, :on => :a
89
+ assert !a.has_exit_code?(1, :on => :b)
90
+
91
+ a.errors.instance_variable_set(:@codes, {:a => [1,2]})
92
+ assert a.has_exit_code? 1
93
+ assert a.has_exit_code? 2
94
+ assert a.has_exit_code? 1, :on => 'a'
95
+ assert a.has_exit_code? 1, :on => :a
96
+ assert !a.has_exit_code?(1, :on => :b)
97
+ end
98
+
99
+ def test_raise_correct_invalid
100
+ ActiveResource::HttpMock.respond_to do |mock|
101
+ mock.post '/broker/rest/domains.json', json_header(true), {:messages => [{:field => 'foo', :exit_code => 1, 'text' => 'bar'}], :data => nil}.to_json, 500
102
+ end
103
+ assert_raise(ActiveResource::ResourceInvalid){ Domain.new(:id => 'a', :as => @user).save! }
104
+
105
+ ActiveResource::HttpMock.respond_to do |mock|
106
+ mock.post '/broker/rest/domains.json', json_header(true), {:messages => [{:field => 'foo', :exit_code => 103, 'text' => 'bar'}], :data => nil}.to_json, 500
107
+ end
108
+ assert_raise(Domain::AlreadyExists){ Domain.new(:id => 'a', :as => @user).save! }
109
+ end
110
+
111
+ def test_has_exit_code_real
112
+ ActiveResource::HttpMock.respond_to do |mock|
113
+ mock.post '/broker/rest/domains.json', json_header(true), {:messages => [{:field => 'foo', :exit_code => 1, 'text' => 'bar'}], :data => nil}.to_json, 500
114
+ end
115
+
116
+ d = Domain.new(:id => 'a', :as => @user)
117
+ assert !d.save
118
+ assert d.has_exit_code?(1), d.attributes.pretty_inspect
119
+ assert d.has_exit_code? 1, :on => 'foo'
120
+ assert d.has_exit_code? 1, :on => :foo
121
+ assert !d.has_exit_code?(1, :on => :foobar)
122
+ end
123
+
124
+ def response(contents)
125
+ object = mock
126
+ body = mock
127
+ body.stubs(:body => contents)
128
+ object.stubs(:response => body)
129
+ object
130
+ end
131
+
132
+ def test_decode
133
+ assert obj = RestApi::OpenshiftJsonFormat.new.decode({:data => {:foo => :bar}}.to_json)
134
+ assert_equal 'bar', obj['foo']
135
+ assert_nil obj[:foo]
136
+ end
137
+
138
+ def test_remote_results
139
+ ActiveResource::HttpMock.respond_to do |mock|
140
+ mock.get '/broker/rest/bases/1.json', json_header, {:messages => [{:field => 'result', :text => 'text'}],:data => {}}.to_json
141
+ end
142
+ assert obj = RestApi::Base.find(1, :as => @user)
143
+ assert_equal ['text'], obj.remote_results
144
+ end
145
+
146
+ def test_has_user_agent
147
+ agent = User.headers['User-Agent']
148
+ assert Console.config.api[:user_agent] =~ %r{\Aopenshift_console/[\w\.]+ \(.*?\)\Z}, Console.config.api[:user_agent]
149
+ assert_equal Console.config.api[:user_agent], agent
150
+ assert_equal RestApi::Base.headers['User-Agent'], agent
151
+ end
152
+
153
+ def test_load_remote_errors
154
+ #assert_raise RestApi::BadServerResponseError do RestApi::Base.new.load_remote_errors(stub(:response => {})); end
155
+ #assert_raise RestApi::BadServerResponseError do RestApi::Base.new.load_remote_errors(stub(:response => stub(:body => nil))); end
156
+ #assert_raise RestApi::BadServerResponseError do RestApi::Base.new.load_remote_errors(stub(:response => stub(:body => ''))); end
157
+ #assert_raise RestApi::BadServerResponseError do RestApi::Base.new.load_remote_errors(stub(:response => stub(:body => ActiveSupport::JSON.encode({})))); end
158
+ #assert_raise RestApi::BadServerResponseError do RestApi::Base.new.load_remote_errors(stub(:response => stub(:body => ActiveSupport::JSON.encode({:messages => nil})))); end
159
+ begin
160
+ RestApi::Base.new.load_remote_errors(response(''))
161
+ rescue RestApi::BadServerResponseError => e
162
+ assert_equal '', e.to_s
163
+ end
164
+ begin
165
+ RestApi::Base.new.load_remote_errors(response('{mal'))
166
+ rescue RestApi::BadServerResponseError => e
167
+ assert_equal '{mal', e.to_s
168
+ end
169
+ assert RestApi::Base.new.load_remote_errors(stub(:response => stub(:body => ActiveSupport::JSON.encode({:messages => []})))).empty?
170
+ assert_equal ['hello'], RestApi::Base.new.load_remote_errors(stub(:response => stub(:body => ActiveSupport::JSON.encode({:messages => [{:text => 'hello'}]}))))[:base]
171
+ assert_equal ['hello'], RestApi::Base.new.load_remote_errors(stub(:response => stub(:body => ActiveSupport::JSON.encode({:messages => [{:field => 'test', :text => 'hello'}]}))))[:test]
172
+ end
173
+
174
+ class TestExitCodeException < ActiveResource::ConnectionError ; end
175
+ class ExitCode < RestApi::Base
176
+ on_exit_code 124, TestExitCodeException
177
+ on_exit_code 125 do |errors, code, field, text|
178
+ errors.add(:base, "Something awful")
179
+ end
180
+ end
181
+
182
+ def test_exit_code_raises
183
+ response = stub(:response => stub(:body => ActiveSupport::JSON.encode({:messages => [{:field => 'test', :text => 'hello', :exit_code => 124}]})))
184
+ assert_raise TestExitCodeException do ExitCode.new.load_remote_errors(response, true, true) end
185
+ assert RestApi::Base.new.load_remote_errors(response, true, true)
186
+
187
+ response = stub(:response => stub(:code => 500, :body => ActiveSupport::JSON.encode({:messages => [{:field => 'test', :text => 'hello', :exit_code => 124}]})))
188
+ assert_raise TestExitCodeException do ExitCode.new.load_remote_errors(response, true, true) end
189
+
190
+ response = stub(:response => stub(:code => 409, :body => ActiveSupport::JSON.encode({:messages => [{:field => 'test', :text => 'hello', :exit_code => 124}]})))
191
+ assert_raise TestExitCodeException do ExitCode.new.load_remote_errors(response, true, true) end
192
+
193
+ response = stub(:response => stub(:body => ActiveSupport::JSON.encode({:messages => [{:field => 'test', :text => 'hello', :exit_code => 123}]})))
194
+ assert RestApi::Base.new.load_remote_errors(response, true, true)
195
+ end
196
+
197
+ def test_exit_code_modifies_errors
198
+ response = stub(:response => stub(:body => ActiveSupport::JSON.encode({:messages => [{:field => 'test', :text => 'hello', :exit_code => 125}]})))
199
+ assert (obj = ExitCode.new).load_remote_errors(response, true, true)
200
+ assert_equal obj.errors[:base], ["Something awful"]
201
+ assert (obj = RestApi::Base.new).load_remote_errors(response, true, true)
202
+ assert_equal obj.errors[:test], ["hello"]
203
+ end
204
+
205
+ def test_check_errors
206
+ response = stub(:body => ActiveSupport::JSON.encode({:messages => [{:field => 'test', :text => 'hello', :exit_code => 125}]}))
207
+ assert errors = RestApi::Base.remote_errors_for(response)
208
+ assert_equal 1, errors.length
209
+ assert_equal [125, 'test', 'hello'], errors[0]
210
+ end
211
+
212
+ def test_serialization
213
+ app = Application.new :name => 'test1', :cartridge => 'cool', :application_type => 'diy-0.1', :as => @user
214
+ #puts app.class.send('known_attributes').inspect
215
+ app.serializable_hash
216
+ end
217
+
218
+ class Calculated < RestApi::Base
219
+ schema do
220
+ string :first, :last
221
+ end
222
+ attr_alters :together, [:first, :last]
223
+ attr_alters :together_nil, [:first, :last]
224
+ def together=(together)
225
+ self.first, self.last = together.split if together
226
+ super
227
+ end
228
+ def together_nil=(together)
229
+ if together
230
+ self.first, self.last = together.split
231
+ else
232
+ self.first = nil
233
+ self.last = nil
234
+ end
235
+ super
236
+ end
237
+
238
+ alias_attribute :start, :first
239
+
240
+ validates :first, :length => {:maximum => 1},
241
+ :presence => true,
242
+ :allow_blank => false
243
+ validates :last, :length => {:minimum => 2},
244
+ :presence => true,
245
+ :allow_blank => false
246
+ end
247
+
248
+ def test_alias_assign
249
+ c = Calculated.new :start => 'a'
250
+ assert_equal 'a', c.start
251
+
252
+ c = Calculated.new :start => 'a', :first => nil
253
+ assert_equal nil, c.start
254
+
255
+ c = Calculated.new :start => 'a', :first => 'b'
256
+ assert_equal 'b', c.start
257
+
258
+ c = Calculated.new :start => nil, :first => 'b'
259
+ assert_equal 'b', c.start
260
+ end
261
+
262
+ def test_alias_error
263
+ c = Calculated.new
264
+ c.valid?
265
+ assert_equal ["can't be blank"], c.errors[:first]
266
+ assert_equal ["can't be blank"], c.errors[:start]
267
+ end
268
+
269
+ def test_calculated_attr
270
+ c = Calculated.new
271
+ assert_equal 'a b', c.together = 'a b'
272
+ assert_equal 'a b', c.attributes[:together]
273
+ assert_equal 'a', c.first
274
+ assert_equal 'b', c.last
275
+
276
+ c = Calculated.new :together => 'a b'
277
+ assert_equal 'a b', c.together
278
+ assert_equal 'a b', c.attributes[:together]
279
+ assert_equal 'a', c.first
280
+ assert_equal 'b', c.last
281
+
282
+ c = Calculated.new.load(:together => 'a b')
283
+ assert_equal 'a b', c.together
284
+ assert_equal 'a', c.first
285
+ assert_equal 'b', c.last
286
+
287
+ c = Calculated.new :first => 'c', :last => 'd'
288
+ assert_equal 'a b', c.together = 'a b'
289
+ assert_equal 'a', c.first
290
+ assert_equal 'b', c.last
291
+
292
+ c = Calculated.new :together => 'a b', :first => 'c', :last => 'd'
293
+ assert_equal 'a', c.first
294
+ assert_equal 'b', c.last
295
+
296
+ c = Calculated.new :together => nil, :first => 'c', :last => 'd'
297
+ assert_equal 'c', c.first
298
+ assert_equal 'd', c.last
299
+
300
+ c = Calculated.new :together_nil => nil, :first => 'c', :last => 'd'
301
+ assert_nil c.first
302
+ assert_nil c.last
303
+ end
304
+
305
+ def test_calculated_errors
306
+ c = Calculated.new :first => 'ab', :last => 'c'
307
+ assert !c.valid?
308
+ assert c.errors[:first].length == 1
309
+ assert c.errors[:last].length == 1
310
+ assert_equal 2, c.errors[:together].length
311
+ assert c.errors[:together].include? c.errors[:first][0]
312
+ assert c.errors[:together].include? c.errors[:last][0]
313
+ end
314
+
315
+ class Observed < RestApi::Base
316
+ end
317
+
318
+ class Observer < ActiveModel::Observer
319
+ observe RestApiTest::Observed
320
+ def after_save(domain)
321
+ puts "save"
322
+ end
323
+ def after_create(domain)
324
+ puts "create"
325
+ end
326
+ end
327
+ def test_observed
328
+ Observed.observers = Observer
329
+ Observed.instantiate_observers
330
+
331
+ Observer.any_instance.expects(:after_save)
332
+ Observer.any_instance.expects(:after_create)
333
+ ActiveResource::HttpMock.respond_to do |mock|
334
+ mock.post '/broker/rest/observeds.json', json_header(true), {}.to_json
335
+ end
336
+
337
+ o = Observed.new :as => @user
338
+ o.save
339
+ end
340
+
341
+ def test_domain_observed
342
+ assert RestApi::Base.observers.include?(DomainSessionSweeper)
343
+ end
344
+
345
+ def test_client_key_validation
346
+ key = Key.new :type => 'ssh-rsa', :name => 'test2', :as => @user
347
+ assert !key.save
348
+ assert_equal 1, key.errors[:content].length
349
+
350
+ key.content = ''
351
+ assert !key.save
352
+ assert_equal 1, key.errors[:content].length
353
+
354
+ key.content = 'a'
355
+
356
+ ActiveResource::HttpMock.respond_to do |mock|
357
+ mock.post '/broker/rest/user/keys.json', json_header(true), key.to_json
358
+ end
359
+
360
+ assert key.save
361
+ assert key.errors.empty?
362
+ end
363
+
364
+ class ReflectedTest < ActiveResource::Base
365
+ self.site = "http://localhost"
366
+ end
367
+
368
+ def test_create_safe_reflected_name
369
+ base = ReflectedTest.new
370
+ r = base.send("find_or_create_resource_for", 'mysql-5.1')
371
+ assert_equal 'RestApiTest::ReflectedTest::Mysql51', r.name, r.pretty_inspect
372
+ end
373
+
374
+ def test_create_cookie
375
+ base_connection = ActiveResource::PersistentConnection.new 'http://localhost', :xml
376
+ connection = RestApi::UserAwareConnection.new base_connection, RestApi::Authorization.new('test1', '1234')
377
+ headers = connection.authorization_header(:post, '/something')
378
+ assert_equal 'rh_sso=1234', headers['Cookie']
379
+ end
380
+
381
+ def test_reuse_connection
382
+ ActiveResource::HttpMock.enabled = false
383
+ auth1 = RestApi::Authorization.new('test1', '1234', 'pass1')
384
+ auth2 = RestApi::Authorization.new('test2', '12345', 'pass2')
385
+
386
+ assert connection = RestApi::Base.connection(:as => auth1)
387
+ assert connection1 = RestApi::Base.connection(:as => auth1)
388
+ assert connection2 = RestApi::Base.connection(:as => auth2)
389
+
390
+ assert_same connection.send(:http), connection1.send(:http)
391
+ assert_same connection.send(:http), connection2.send(:http)
392
+
393
+ assert_equal 'test1', connection.user
394
+ assert_equal 'test1', connection1.user
395
+ assert_equal 'test2', connection2.user
396
+
397
+ assert_equal auth1.password, connection1.password
398
+ assert_equal auth2.password, connection2.password
399
+ end
400
+
401
+ def test_update_method_patch
402
+ resource = Class.new(RestApi::Base) do
403
+ schema{ string :id }
404
+ self.element_name = 'test'
405
+ use_patch_on_update
406
+ end.new({:id => 'test', :as => @user}, true)
407
+
408
+ ActiveResource::HttpMock.respond_to do |mock|
409
+ mock.patch '/broker/rest/tests/test.json', json_header(true), {:id => 'test', :loaded => true}.to_json
410
+ end
411
+
412
+ assert resource.save
413
+ assert resource.loaded
414
+ end
415
+
416
+ def test_load_returns_self
417
+ key = Key.new
418
+ assert_equal key, key.load({})
419
+ end
420
+
421
+ def test_find_one_raises_resource_not_found
422
+ ActiveResource::HttpMock.respond_to do |mock|
423
+ mock.get '/broker/rest/user.json', json_header, nil, 404
424
+ end
425
+ begin
426
+ User.find :one, :as => @user
427
+ flunk "Expected to raise RestApi::ResourceNotFound"
428
+ rescue RestApi::ResourceNotFound => e
429
+ assert_equal User, e.model
430
+ assert_equal nil, e.id
431
+ assert !e.domain_missing?
432
+ assert e.to_s =~ /User does not exist/
433
+ end
434
+ end
435
+
436
+ def test_find_single_raises_resource_not_found
437
+ ActiveResource::HttpMock.respond_to do |mock|
438
+ mock.get '/broker/rest/domains/foo.json', json_header, nil, 404
439
+ end
440
+ begin
441
+ Domain.find 'foo', :as => @user
442
+ flunk "Expected to raise RestApi::ResourceNotFound"
443
+ rescue RestApi::ResourceNotFound => e
444
+ assert_equal Domain, e.model
445
+ assert_equal 'foo', e.id
446
+ assert !e.domain_missing?
447
+ assert e.to_s =~ /Domain 'foo' does not exist/
448
+ end
449
+ end
450
+
451
+ def test_find_single_raises_resource_not_found
452
+ ActiveResource::HttpMock.respond_to do |mock|
453
+ mock.get '/broker/rest/domains/foo/applications/bar.json', json_header, nil, 404
454
+ end
455
+ begin
456
+ Application.find 'bar', :as => @user, :params => {:domain_id => 'foo'}
457
+ flunk "Expected to raise RestApi::ResourceNotFound"
458
+ rescue RestApi::ResourceNotFound => e
459
+ assert_equal Application, e.model
460
+ assert_equal 'bar', e.id
461
+ assert !e.domain_missing?
462
+ assert e.to_s =~ /Application 'bar' does not exist/
463
+ end
464
+ end
465
+
466
+ def test_find_application_fetch_detects_domain_missing
467
+ ActiveResource::HttpMock.respond_to do |mock|
468
+ mock.get '/broker/rest/domains/foo/applications/bar.json', json_header, {:messages => [{:exit_code => 127}]}.to_json, 404
469
+ end
470
+ begin
471
+ Application.find 'bar', :as => @user, :params => {:domain_id => 'foo'}
472
+ flunk "Expected to raise RestApi::ResourceNotFound"
473
+ rescue RestApi::ResourceNotFound => e
474
+ assert_equal Application, e.model
475
+ assert_equal 'bar', e.id
476
+ assert e.domain_missing?
477
+ assert e.to_s =~ /Application 'bar' does not exist/
478
+ end
479
+ end
480
+
481
+ def test_user_get
482
+ ActiveResource::HttpMock.respond_to do |mock|
483
+ mock.get '/broker/rest/user.json', json_header, { :login => 'test1' }.to_json()
484
+ end
485
+
486
+ user = User.find :one, :as => @user
487
+ assert user
488
+ assert_equal @user.login, user.login
489
+ end
490
+
491
+ def test_custom_id_rename
492
+ ActiveResource::HttpMock.respond_to do |mock|
493
+ mock.get '/broker/rest/domains.json', json_header, [{:id => 'a'}].to_json
494
+ mock.put '/broker/rest/domains/a.json', json_header(true), {:id => 'b'}.to_json
495
+ end
496
+
497
+ domain = Domain.first :as => @user
498
+ assert_equal 'a', domain.name
499
+ assert_equal '/broker/rest/domains/a.json', domain.send(:element_path)
500
+
501
+ domain.name = 'b'
502
+
503
+ assert_equal 'a', domain.id_was
504
+ assert_equal 'b', domain.id
505
+ assert_equal 'b', domain.name
506
+ assert_equal '/broker/rest/domains/a.json', domain.send(:element_path)
507
+ assert domain.save
508
+
509
+ domain = Domain.new({:name => 'a'}, true)
510
+ domain.attributes = {:name => 'b'}
511
+ assert_equal 'a', domain.id_was
512
+ assert_equal 'b', domain.id
513
+ assert_equal 'b', domain.name
514
+ assert_equal '/broker/rest/domains/a.json', domain.send(:element_path)
515
+ end
516
+
517
+ class DomainWithValidation < Domain
518
+ self.element_name = 'domain'
519
+ validates :id, :length => {:maximum => 1},
520
+ :presence => true,
521
+ :allow_blank => false
522
+ end
523
+
524
+ def test_custom_id_rename_with_validation
525
+ ActiveResource::HttpMock.respond_to do |mock|
526
+ mock.get '/broker/rest/domains.json', json_header, [{:id => 'a'}].to_json
527
+ mock.put '/broker/rest/domains/a.json', json_header(true), {:id => 'b'}.to_json
528
+ end
529
+ t = DomainWithValidation.first :as => @user
530
+ assert_equal 'a', t.id_was
531
+ assert t.persisted?
532
+ assert !t.changed?, t.inspect
533
+ t.name = 'ab'
534
+ assert t.changed?
535
+ assert !t.save, t.pretty_inspect
536
+ assert t.changed?
537
+ assert_equal 'a', t.id_was, t.inspect
538
+
539
+ t.name = 'b'
540
+ assert t.save
541
+ assert_equal 'b', t.id_was
542
+ end
543
+
544
+ def test_info_raises_error
545
+ assert_raises RestApi::ApiNotAvailable do
546
+ RestApi.info
547
+ end
548
+ end
549
+
550
+ def test_info_hits_server
551
+ ActiveResource::HttpMock.respond_to do |mock|
552
+ mock.get '/broker/rest/api.json', anonymous_json_header, {:version => '1.0.0'}.to_json
553
+ end
554
+ info = RestApi.info
555
+ assert info
556
+ assert_equal '1.0.0', info.version
557
+ end
558
+
559
+ def test_key_make_unique_noop
560
+ key = Key.new({:name => 'key'}, true)
561
+ key.expects(:connection).never.expects(:as).never
562
+ assert_equal 'key', key.make_unique!.name
563
+ end
564
+
565
+ def test_key_make_unique
566
+ ActiveResource::HttpMock.respond_to do |mock|
567
+ mock.get '/broker/rest/user/keys.json', json_header, [].to_json
568
+ end
569
+ assert_equal 'key', Key.new(:name => 'key', :as => @user).make_unique!.name
570
+ assert_equal 'key', Key.new(:name => 'key', :as => @user).make_unique!('key %s').name
571
+
572
+ ActiveResource::HttpMock.respond_to do |mock|
573
+ mock.get '/broker/rest/user/keys.json', json_header, [{:name => 'key'}].to_json
574
+ end
575
+ assert_equal 'key 2', Key.new(:name => 'key', :as => @user).make_unique!.name
576
+ assert_equal 'new key 2', Key.new(:name => 'key', :as => @user).make_unique!('new key %s').name
577
+
578
+ ActiveResource::HttpMock.respond_to do |mock|
579
+ mock.get '/broker/rest/user/keys.json', json_header, [{:name => 'key'}, {:name => 'key 2'}].to_json
580
+ end
581
+ assert_equal 'key 3', Key.new(:name => 'key', :as => @user).make_unique!.name
582
+ assert_equal 'new key 2', Key.new(:name => 'key', :as => @user).make_unique!('new key %s').name
583
+ end
584
+
585
+ def test_key_attributes
586
+ key = Key.new
587
+ assert_nil key.name
588
+ assert_nil key.content
589
+ assert_nil key.raw_content
590
+ assert_nil key.type
591
+
592
+ key.name = 'a'
593
+
594
+ key.raw_content = 'ssh-rsa key'
595
+ assert_equal 'ssh-rsa', key.type
596
+ assert_equal 'key', key.content
597
+
598
+ key = Key.new :raw_content => 'ssh-rsa key'
599
+ assert_equal 'ssh-rsa', key.type
600
+ assert_equal 'key', key.content
601
+
602
+ key = Key.new :raw_content => 'ssh-rsa key', :type => 'fish'
603
+ assert_equal 'ssh-rsa', key.type
604
+ assert_equal 'key', key.content
605
+
606
+ key = Key.new :raw_content => 'ssh-rsa key test'
607
+ assert_equal 'ssh-rsa', key.type
608
+ assert_equal 'key', key.content
609
+
610
+ key = Key.new :raw_content => 'ecdsa-sha2-nistp52 key test'
611
+ assert_equal 'ecdsa-sha2-nistp52', key.type
612
+ assert_equal 'key', key.content
613
+
614
+ key = Key.new :raw_content => 'ssh-dss key test'
615
+ assert_equal 'ssh-dss', key.type
616
+ assert_equal 'key', key.content
617
+
618
+ key = Key.new :raw_content => 'key'
619
+ assert_nil key.type
620
+ assert_equal 'key', key.content
621
+
622
+ contents = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBJHobjmzxy8cv9A1xw9X5TlnQd0bW/19FwOC0c6jPNu9ZbtWQcAE0xfODl7ZqVPPU2qAFOh4rbL3gL2UzTyA+NwERyDrH7tMXAoXPT2L6sqExl0xxuEvb/lXUfLquMq+BMOFxxqCEg8X7GavHN72FMUHwweNybE7C82So+OFSWqFoctiWMNdNsKW4lvBd/jkIudGdRdK+/PzV75TW1LcpfsBrFOJZbd5WzDJEPNdMqOH68YDExD82VtzeJm0HEavhMY9HtxIDEmjIhtfedzCGZLe+6OxReuatw6M+n1sFxT9liprZ6NIANvbnYZKGT50hYfnIi/hZOTCvqYNS97O3 openshift Aug 2012'
623
+ key = Key.new :raw_content => contents
624
+ assert_equal 'ssh-rsa', key.type
625
+ assert_equal contents.split(' ')[1], key.content
626
+ end
627
+
628
+ def test_domain_to_json
629
+ assert_equal '{"id":5}', Domain.new(:id => 5).to_json
630
+ end
631
+
632
+ def test_domain_throws_on_find_one
633
+ ActiveResource::HttpMock.respond_to do |mock|
634
+ mock.get '/broker/rest/domains.json', json_header, [].to_json
635
+ end
636
+
637
+ assert_nil Domain.first :as => @user
638
+ assert_raise RestApi::ResourceNotFound do
639
+ Domain.find :one, :as => @user
640
+ end
641
+ end
642
+
643
+ def test_domain_find_one
644
+ ActiveResource::HttpMock.respond_to do |mock|
645
+ mock.get '/broker/rest/domains.json', json_header, [{:id => 'a'}].to_json
646
+ end
647
+
648
+ assert Domain.first :as => @user
649
+ assert Domain.find :one, :as => @user
650
+ end
651
+
652
+ def test_app_reload
653
+ ActiveResource::HttpMock.respond_to do |mock|
654
+ mock.get '/broker/rest/domains.json', json_header, [{:id => 'a'}].to_json
655
+ mock.get '/broker/rest/domains/a/applications.json', json_header, [{:name => 'a'}].to_json
656
+ mock.get '/broker/rest/domains/a/applications/a.json', json_header, {:name => 'a', :git_url => 'test'}.to_json
657
+ end
658
+ app = Domain.find(:one, :as => @user).applications.first
659
+ assert_nil app.git_url
660
+
661
+ options = app.prefix_options.dup
662
+ assert !options.empty?
663
+
664
+ app.reload
665
+ assert_equal 'test', app.git_url
666
+
667
+ assert_equal options, app.prefix_options
668
+ end
669
+
670
+ def test_prefix_option_during_reload
671
+ ActiveResource::HttpMock.respond_to do |mock|
672
+ mock.get '/broker/rest/domains/a/applications/b/cartridges/foo.json', json_header, {:name => 'foo'}.to_json
673
+ end
674
+ cart = Cartridge.find 'foo', :as => @user, :params => {:domain_id => 'a', :application_name => 'b'}
675
+ assert_equal({:domain_id => 'a', :application_name => 'b'}, cart.prefix_options)
676
+ cart.reload
677
+ assert_equal({:domain_id => 'a', :application_name => 'b'}, cart.prefix_options)
678
+ end
679
+
680
+ def test_prefix_option_during_save
681
+ ActiveResource::HttpMock.respond_to do |mock|
682
+ mock.get '/broker/rest/domains/a/applications/b/cartridges/foo.json', json_header, {:name => 'foo'}.to_json
683
+ mock.put '/broker/rest/domains/a/applications/b/cartridges/foo.json', json_header(true), {:name => 'foo'}.to_json
684
+ end
685
+ prefix_options = {:domain_id => 'a', :application_name => 'b'}
686
+ cart = Cartridge.find 'foo', :as => @user, :params => prefix_options
687
+ assert_equal prefix_options, cart.prefix_options
688
+ cart.save
689
+ assert_equal prefix_options, cart.prefix_options
690
+ end
691
+
692
+ def test_domain_reload
693
+ ActiveResource::HttpMock.respond_to do |mock|
694
+ mock.get '/broker/rest/domains.json', json_header, [{:id => 'a'}].to_json
695
+ mock.get '/broker/rest/domains/a.json', json_header, {:id => 'a'}.to_json
696
+ end
697
+ domain = Domain.find :one, :as => @user
698
+ oldname = domain.name
699
+ domain.name = 'foo'
700
+ assert_equal 'foo', domain.name
701
+ domain.reload
702
+ assert_equal oldname, domain.name
703
+ end
704
+ def test_domain_names
705
+ domain = Domain.new
706
+ assert_nil domain.name
707
+ assert_nil domain.name
708
+ assert !domain.changed?
709
+ domain = Domain.new({:id => 1}, true)
710
+ domain.name = '1'
711
+ assert domain.changed?
712
+ assert domain.id_changed?
713
+ assert_equal '1', domain.id
714
+ assert_equal '1', domain.name, domain.name
715
+ assert_equal '1', domain.to_param
716
+ domain.name = '2'
717
+ # id should only change on either first update or save
718
+ assert_equal '2', domain.id
719
+ assert_equal '2', domain.name
720
+ assert_equal '1', domain.to_param
721
+ domain.name = '3'
722
+ assert_equal '3', domain.id
723
+ assert_equal '1', domain.to_param
724
+
725
+ domain = Domain.new :name => 'hello'
726
+ assert_equal 'hello', domain.name, domain.name
727
+
728
+ domain = Domain.new :name => 'hello'
729
+ assert_equal 'hello', domain.name, domain.name
730
+ end
731
+
732
+ def test_domain_assignment_to_application
733
+ app = Application.new :domain_name => '1'
734
+ assert_equal '1', app.domain_id, app.pretty_inspect
735
+ assert_equal '1', app.domain_name
736
+
737
+ app = Application.new :domain_id => '1'
738
+ assert_equal '1', app.domain_id, app.domain_name
739
+
740
+ app = Application.new :as => @user
741
+ assert_nil app.domain_id
742
+ assert_nil app.domain_name
743
+
744
+ app.domain_id = 'test'
745
+ assert_equal 'test', app.domain_id, app.domain_name
746
+
747
+ app.domain_name = 'test2'
748
+ assert_equal 'test2', app.domain_id, app.domain_name
749
+ end
750
+
751
+ def test_domain_object_assignment_to_application
752
+ ActiveResource::HttpMock.respond_to do |mock|
753
+ mock.get '/broker/rest/domains/test3.json', json_header, { :id => 'test3' }.to_json()
754
+ end
755
+
756
+ app = Application.new :as => @user
757
+ domain = Domain.new :name => 'test3'
758
+
759
+ app.domain_name = domain.name
760
+ assert_equal domain, app.domain
761
+
762
+ app = Application.new :as => @user
763
+ app.domain = domain
764
+ assert_equal domain.name, app.domain_id
765
+ assert_equal domain.name, app.domain_name
766
+ assert_equal domain.name, domain.id
767
+ end
768
+
769
+ def opts1() {:name => 'app1', :cartridge => 'php-5.3'} ; end
770
+ def opts2() {:name => 'app2', :cartridge => 'php-5.3'} ; end
771
+ def app1() Application.new({:as => @user}.merge(opts1)) ; end
772
+ def app2() Application.new({:as => @user}.merge(opts2)) ; end
773
+
774
+ def test_domain_applications
775
+ ActiveResource::HttpMock.respond_to do |mock|
776
+ mock.get '/broker/rest/domains.json', json_header, [{ :id => 'a' }].to_json
777
+ mock.get '/broker/rest/domains/a/applications.json', json_header, [opts1, opts2].to_json
778
+ end
779
+
780
+ domain = Domain.find :one, :as => @user
781
+
782
+ apps = domain.applications
783
+ assert_attr_equal [app1, app2], apps
784
+ end
785
+
786
+ def test_domain_applications_reload
787
+ with_apps = lambda do |mock|
788
+ mock.get '/broker/rest/domains.json', json_header, [{ :id => 'a' }].to_json
789
+ mock.get '/broker/rest/domains/a.json', json_header, { :id => 'a' }.to_json
790
+ mock.get '/broker/rest/domains/a/applications.json', json_header, [opts1, opts2].to_json
791
+ end
792
+
793
+ ActiveResource::HttpMock.respond_to &with_apps
794
+ domain = Domain.find :one, :as => @user
795
+
796
+ cache = states('cache').starts_as('empty')
797
+ Application.expects(:find).once.returns([Application.new(opts1), Application.new(opts2)]).then(cache.is('full'))
798
+ Application.expects(:find).never.when(cache.is('full'))
799
+
800
+ domain.expects(:reload).once.then(cache.is('empty'))
801
+
802
+ assert apps = domain.applications
803
+ assert_attr_equal [app1, app2], apps
804
+
805
+ assert_attr_equal [app1, app2], domain.applications
806
+
807
+ domain.reload
808
+
809
+ assert_equal [app1, app2], domain.applications
810
+ end
811
+
812
+ def test_domain_find_applications
813
+ ActiveResource::HttpMock.respond_to do |mock|
814
+ mock.get '/broker/rest/domains.json', json_header, [{ :id => 'a' }].to_json
815
+ mock.get '/broker/rest/domains/a/applications/app1.json', json_header, opts1.to_json
816
+ mock.get '/broker/rest/domains/a/applications/app2.json', json_header, opts2.to_json
817
+ mock.get '/broker/rest/domains/a/applications/app3.json', json_header, nil, 404
818
+ end
819
+
820
+ domain = Domain.find :one, :as => @user
821
+ assert_attr_equal app1, domain.find_application('app1')
822
+ assert_attr_equal app2, domain.find_application('app2')
823
+ assert_raise(RestApi::ResourceNotFound) { domain.find_application 'app3' }
824
+ end
825
+
826
+ def test_cartridges
827
+ ActiveResource::HttpMock.respond_to do |mock|
828
+ mock.get '/broker/rest/cartridges/embedded', json_header
829
+ end
830
+
831
+ app = Application.new :name => 'testapp1', :as => @user
832
+ domain = Domain.new :name => 'test3'
833
+ app.domain = domain
834
+
835
+ cart = Cartridge.new
836
+ cart.application = app
837
+
838
+ assert_equal '/broker/rest/domains/test3/applications/testapp1/cartridges.json', cart.send(:collection_path)
839
+ end
840
+
841
+ def test_cartridge_assignment
842
+ cart = Cartridge.new
843
+ app = Application.new :name => 'testapp1', :domain_name => 'test3'
844
+ cart.application = app
845
+
846
+ assert_equal '/broker/rest/domains/test3/applications/testapp1/cartridges.json', cart.send(:collection_path)
847
+ end
848
+
849
+ def test_cartridges_assignment
850
+ app = Application.new
851
+ assert_equal [], app.cartridges
852
+ app.cartridges = ['foo']
853
+ assert_equal ['foo'], app.attributes[:cartridges]
854
+ assert_equal ['foo'], app.cartridge_names
855
+ assert_equal [], app.cartridges
856
+ app.cartridge_names = ['bar']
857
+ assert_equal ['bar'], app.attributes[:cartridges]
858
+ assert_equal ['bar'], app.cartridge_names
859
+
860
+ app.assign_attributes(:cartridges => ['a','b'])
861
+ assert_equal ['a','b'], app.attributes[:cartridges]
862
+
863
+ app.assign_attributes(:cartridge_names => ['c','d'])
864
+ assert_equal ['c','d'], app.attributes[:cartridges]
865
+
866
+ app = Application.new({:name => 'a', :domain_name => 'b'}, true)
867
+ Cartridge.expects(:find).once.with(:all, :as => nil, :params => {:application_name => 'a', :domain_id => 'b'}).returns([Cartridge.new(:name => 'test')])
868
+ carts = app.cartridges
869
+ assert_equal [Cartridge.new(:name => 'test')], carts
870
+ assert_same carts, app.cartridges
871
+ assert_equal ['test'], app.cartridge_names
872
+ end
873
+
874
+ def test_cartridge_initialization_object
875
+ app = Application.new :name => 'testapp1', :domain_id => 'test3'
876
+ cart = Cartridge.new :application => app
877
+
878
+ assert_equal app.name, cart.application_name
879
+
880
+ Application.expects(:find).with(app.name, :params => {:domain_id => app.domain_id}, :as => nil).returns(app)
881
+ assert_equal app.name, cart.application.name
882
+
883
+ assert_equal '/broker/rest/domains/test3/applications/testapp1/cartridges.json', cart.send(:collection_path)
884
+ end
885
+
886
+ def test_cartridge_assignment_object
887
+ app = Application.new :name => 'testapp1', :domain_id => 'test3'
888
+ cart = Cartridge.new
889
+ cart.application = app
890
+
891
+ assert_equal app.name, cart.application_name
892
+
893
+ Application.expects(:find).with(app.name, :params => {:domain_id => app.domain_id}, :as => nil).returns(app)
894
+ assert_equal app.name, cart.application.name
895
+
896
+ assert_equal '/broker/rest/domains/test3/applications/testapp1/cartridges.json', cart.send(:collection_path)
897
+ end
898
+
899
+ def test_gear_assigns_as
900
+ [Domain, Application, Key, Cartridge, Gear].each do |klass|
901
+ assert_equal @user, klass.new(:as => @user).send(:as)
902
+ end
903
+ [Domain, Application, Key, Cartridge, Gear].each do |klass|
904
+ (obj = klass.new).as = @user
905
+ assert_equal @user, obj.send(:as)
906
+ end
907
+ end
908
+
909
+ def test_app_domain_assignment_transfers_as
910
+ app = Application.new :domain => Domain.new(:id => '1', :as => @user)
911
+ assert_equal @user, app.send(:as)
912
+ end
913
+
914
+ def test_app_cart_assignment_transfers_as
915
+ cart = Cartridge.new :application => Application.new(:as => @user)
916
+ assert_equal @user, cart.send(:as)
917
+ end
918
+
919
+ def test_app_domain_object_assignment
920
+ domain = Domain.new({:id => "1"}, true)
921
+ app = Application.new({:name => 'testapp1', :domain => domain}, true)
922
+ assert_equal 'testapp1', app.to_param
923
+ assert_equal domain.id, app.domain_id
924
+ assert_equal '/broker/rest/domains/1/applications/testapp1.json', app.send(:element_path)
925
+
926
+ app = Application.new({:name => 'testapp1'}, true)
927
+ app.domain = domain
928
+ assert_equal domain.id, app.domain_id
929
+ assert_equal '/broker/rest/domains/1/applications/testapp1.json', app.send(:element_path)
930
+ end
931
+
932
+ def test_app_custom_get_method
933
+ ActiveResource::HttpMock.respond_to do |mock|
934
+ mock.get '/broker/rest/domains/1/applications/custom_app_get/gears.json', json_header, [
935
+ { :uuid => 'abc', :components => [ { :name => 'ruby-1.8' } ] },
936
+ ].to_json
937
+ end
938
+ app = Application.new :name => 'custom_app_get', :domain => Domain.new(:id => '1', :as => @user)
939
+ assert_equal({:domain_id => '1'}, app.prefix_options)
940
+ assert_equal 1, (gears = app.gears).length
941
+ assert_equal 'abc', (gear = gears[0]).uuid
942
+ assert_equal 1, gear.components.length
943
+ assert_equal 'ruby-1.8', gear.components[0][:name]
944
+ end
945
+
946
+ def test_domain_id_tracks_changes
947
+ d = Domain.new :id => '1'
948
+ assert !d.changed?, d.pretty_inspect
949
+
950
+ d.id = '2'
951
+ assert d.changed?
952
+
953
+ d.id = '1'
954
+ assert d.changed?
955
+
956
+ d.changed_attributes.clear
957
+ assert !d.changed?
958
+ end
959
+
960
+ def test_domain_update_id_reset
961
+ ActiveResource::HttpMock.respond_to do |mock|
962
+ mock.post '/broker/rest/domains.json', json_header(true), {:id => '1'}.to_json
963
+ mock.put '/broker/rest/domains/1.json', json_header(true), {:id => '2'}.to_json
964
+ end
965
+ d = Domain.create :id => '1', :as => @user
966
+ assert !d.changed?, d.pretty_inspect
967
+
968
+ d.id = '2'
969
+ assert_equal '1', d.id_was
970
+ assert d.save
971
+ assert_equal '2', d.id
972
+ end
973
+
974
+ def test_cartridge_type_init
975
+ type = CartridgeType.new :name => 'haproxy-1.4', :display_name => 'Test - haproxy', :website => 'test'
976
+
977
+ # custom attributes
978
+ assert_equal 'Test - haproxy', type.display_name
979
+ assert_equal 'haproxy-1.4', type.name
980
+ assert_equal 'test', type.website
981
+
982
+ # default values
983
+ assert_equal :embedded, type.type
984
+ assert_nil type.version
985
+ assert_equal [:blacklist], type.tags
986
+ end
987
+
988
+ def test_cartridge_type_scalable_check
989
+ assert scalable_type = CartridgeType.new(:name => 'nodejs-0.6', :display_name => 'Node.JS scalable', :website => 'test')
990
+ scalable_type.attributes['supported_scales_from'] = 1
991
+ scalable_type.attributes['supported_scales_to'] = 2
992
+
993
+ # Values are purposely set at higher than 1 in this test
994
+ assert non_scalable_type = CartridgeType.new(:name => 'diy-0.1', :display_name => 'DIY non-scalable', :website => 'test')
995
+ non_scalable_type.attributes['supported_scales_from'] = 3
996
+ non_scalable_type.attributes['supported_scales_to'] = 3
997
+
998
+ assert_equal true, scalable_type.scalable?
999
+ assert_equal false, non_scalable_type.scalable?
1000
+ end
1001
+
1002
+ def test_application_template_scalable_check
1003
+ assert app_template = ApplicationTemplate.new
1004
+ assert_equal false, app_template.scalable?
1005
+ end
1006
+
1007
+ def test_cartridge_type_find
1008
+ ActiveResource::HttpMock.respond_to do |mock|
1009
+ mock.get '/broker/rest/cartridges.json', anonymous_json_header, [
1010
+ {:name => 'haproxy-1.4'},
1011
+ ].to_json
1012
+ end
1013
+ type = CartridgeType.find 'haproxy-1.4'
1014
+
1015
+ # custom attributes
1016
+ assert_equal 'haproxy-1.4', type.display_name
1017
+ assert_equal 'haproxy-1.4', type.name
1018
+ assert_nil type.website
1019
+
1020
+ # default values
1021
+ assert_equal :embedded, type.type
1022
+ assert_nil type.version
1023
+ end
1024
+
1025
+ class CacheableRestApi < RestApi::Base
1026
+ include RestApi::Cacheable
1027
+
1028
+ @count = 0
1029
+ def self.find_single(*args)
1030
+ #puts "find_single: #{caller.join("\n ")}"
1031
+ @count += 1
1032
+ end
1033
+ cache_method :find_single, lambda{ |id, *args| [CacheableRestApi.name, :item, id] }
1034
+
1035
+ def self.find_every(*args)
1036
+ #puts "find_every: #{caller.join("\n ")}"
1037
+ @count += 1
1038
+ end
1039
+ cache_method :find_every, [CacheableRestApi.name, :find_every]
1040
+
1041
+ def self.count
1042
+ @count
1043
+ end
1044
+ end
1045
+
1046
+ class InheritedCacheableRestApi < CacheableRestApi
1047
+ allow_anonymous
1048
+ singleton
1049
+ end
1050
+
1051
+ def test_cacheable_resource
1052
+ Rails.cache.clear
1053
+
1054
+ assert CacheableRestApi.respond_to? :cached
1055
+ cached = CacheableRestApi.cached
1056
+ assert !CacheableRestApi.equal?(cached)
1057
+ assert cached < CacheableRestApi
1058
+ assert_equal CacheableRestApi.name, cached.name
1059
+ assert_equal [:find_every, :find_single], cached.send(:cache_options)[:caches].keys.map(&:to_s).sort.map(&:to_sym)
1060
+
1061
+ assert_same cached, cached.cached
1062
+
1063
+ assert_equal 0, CacheableRestApi.count
1064
+ cached.find 1, :as => @user
1065
+ assert_equal 1, CacheableRestApi.count
1066
+ cached.find 1, :as => @user
1067
+ assert_equal 1, CacheableRestApi.count
1068
+
1069
+ cached.all :as => @user
1070
+ assert_equal 2, CacheableRestApi.count
1071
+ cached.all :as => @user
1072
+ assert_equal 2, CacheableRestApi.count
1073
+ cached.all :as => RestApi::Authorization.new('different')
1074
+ assert_equal 2, CacheableRestApi.count
1075
+ end
1076
+
1077
+ def test_inherited_cacheable_resource
1078
+ ActiveResource::HttpMock.respond_to do |mock|
1079
+ mock.get '/broker/rest/inherited_cacheable_rest_api.json', anonymous_json_header, {:name => 'haproxy-1.4'}.to_json
1080
+ end
1081
+ assert InheritedCacheableRestApi.find :one
1082
+ end
1083
+
1084
+ def test_cacheable_key_for
1085
+ assert_equal [CacheableRestApi.name, :item, 1], CacheableRestApi.send(:cache_key_for, :find_single, 1)
1086
+ assert_equal [CacheableRestApi.name, :item, 2], CacheableRestApi.send(:cache_key_for, :find_single, 2)
1087
+ assert_equal [CacheableRestApi.name, :find_every], CacheableRestApi.send(:cache_key_for, :find_every)
1088
+ end
1089
+
1090
+ def test_cartridge_type_find_invalid
1091
+ ActiveResource::HttpMock.respond_to do |mock|
1092
+ mock.get '/broker/rest/cartridges.json', anonymous_json_header, [
1093
+ {:name => 'haproxy-1.4'},
1094
+ ].to_json
1095
+ end
1096
+
1097
+ type = CartridgeType.new :name => 'haproxy-1.5'
1098
+ assert_equal 'haproxy-1.5', type.name
1099
+ assert_equal 'haproxy-1.5', type.display_name
1100
+ end
1101
+
1102
+ def test_cartridge_delegate_type
1103
+ ActiveResource::HttpMock.respond_to do |mock|
1104
+ mock.get '/broker/rest/cartridges.json', anonymous_json_header, [
1105
+ {:name => 'haproxy-1.4'},
1106
+ ].to_json
1107
+ end
1108
+
1109
+ cart = Cartridge.new :name => 'haproxy-1.4', :as => @user
1110
+ assert_equal cart.display_name, CartridgeType.find(cart.name).display_name
1111
+ assert cart.instance_variable_get(:@cartridge_type)
1112
+
1113
+ cart = Cartridge.new :name => 'haproxy-1.5', :as => @user
1114
+ assert_equal 'haproxy-1.5', cart.display_name
1115
+ end
1116
+
1117
+ def test_dup
1118
+ d = Domain.new :id => 1, :as => @user
1119
+ d2 = d.dup
1120
+ assert_same d.send(:as), d2.send(:as)
1121
+ assert_same d.id, d2.id
1122
+ end
1123
+
1124
+ def test_clone
1125
+ d = Domain.new :id => '1', :as => @user
1126
+ d2 = d.clone
1127
+ assert_same d.send(:as), d2.send(:as)
1128
+ end
1129
+
1130
+ def test_clone_fixnum
1131
+ d = Domain.new :id => '1', :value => 1
1132
+ d2 = d.clone
1133
+ assert_equal d.value, d2.value
1134
+ end
1135
+
1136
+ def test_custom_id_must_be_valid
1137
+ assert_raise(RuntimeError) { Class.new(RestApi::Base) { custom_id "string" } }
1138
+ assert_raise(RuntimeError) { Class.new(RestApi::Base) { custom_id Class } }
1139
+ assert_raise(RuntimeError) { Class.new(RestApi::Base) { custom_id nil } }
1140
+ end
1141
+
1142
+ def test_cartridge_type_tag_sort
1143
+ [
1144
+ [ 1, [:database], [:web_framework]],
1145
+ [ 1, [:foo], [:web_framework]],
1146
+ [ 1, [:foo], [:database]],
1147
+ [ 0, [:web_framework], [:web_framework]],
1148
+ [ 0, [:database], [:database]],
1149
+ [ 0, [:foo], [:bar]],
1150
+ [-1, [:web_framework], [:database]],
1151
+ [-1, [:web_framework], [:foo]],
1152
+ ].each do |val, a, b|
1153
+ assert_equal val, CartridgeType.tag_compare(a, b)
1154
+ end
1155
+ end
1156
+
1157
+ def test_cartridge_type_embedded
1158
+ ActiveResource::HttpMock.respond_to do |mock|
1159
+ mock.get '/broker/rest/cartridges.json', anonymous_json_header, [
1160
+ {:name => 'haproxy-1.4', :type => 'embedded'},
1161
+ ].to_json
1162
+ end
1163
+
1164
+ types = CartridgeType.embedded
1165
+
1166
+ assert_equal 1, types.length
1167
+
1168
+ assert types.none?(&:standalone?)
1169
+ assert types.all?(&:embedded?)
1170
+
1171
+ assert type = types.find {|t| t.name == 'haproxy-1.4'}
1172
+ assert_equal :embedded, type.type
1173
+ assert type.embedded?
1174
+ assert !type.standalone?
1175
+ assert_nil type.version
1176
+ assert_equal CartridgeType.new(:name => 'haproxy-1.4'), type
1177
+ assert_equal 'haproxy-1.4', type.to_param
1178
+ end
1179
+
1180
+ def test_cartridge_type_embedded_cached
1181
+ ActiveResource::HttpMock.respond_to do |mock|
1182
+ mock.get '/broker/rest/cartridges.json', anonymous_json_header, [
1183
+ {:name => 'haproxy-1.4'},
1184
+ ].to_json
1185
+ end
1186
+
1187
+ Rails.cache.clear
1188
+ key = CartridgeType.send(:cache_key_for, :find_every)
1189
+ assert_nil Rails.cache.read(key)
1190
+
1191
+ types = CartridgeType.embedded
1192
+ assert_nil Rails.cache.read(key), "Having the regular call fill the cache may be desirable"
1193
+
1194
+ types = CartridgeType.cached.embedded
1195
+ assert cached = Rails.cache.read(key)
1196
+
1197
+ ActiveResource::HttpMock.reset!
1198
+ assert type = CartridgeType.cached.find('haproxy-1.4')
1199
+ assert_equal 'haproxy-1.4', type.name
1200
+ assert_nil type.send(:as)
1201
+ assert_equal CartridgeType._to_partial_path, type.to_partial_path
1202
+ end
1203
+
1204
+ def test_application_types
1205
+ mock_quickstart
1206
+ ActiveResource::HttpMock.respond_to(false) do |mock|
1207
+ mock.get '/broker/rest/cartridges.json', anonymous_json_header, [
1208
+ {:name => 'haproxy-1.4', :type => 'standalone'},
1209
+ {:name => 'php-5.3', :type => 'standalone', :tags => [:framework]},
1210
+ {:name => 'blacklist', :type => 'standalone', :tags => [:framework, :blacklist]},
1211
+ ].to_json
1212
+
1213
+ mock.get '/broker/rest/application_templates.json', anonymous_json_header, [
1214
+ ].to_json
1215
+ end
1216
+
1217
+ # For this test, stub the scalability logic; we test it separately
1218
+ CartridgeType.any_instance.stubs(:scalable).returns(true)
1219
+
1220
+ types = ApplicationType.find :all
1221
+ assert_equal 2, types.length, types.inspect
1222
+ types.each do |type|
1223
+ assert a = ApplicationType.find(type.id)
1224
+ assert_equal type.id, a.id
1225
+ assert_equal type.description, a.description
1226
+ assert_equal type.categories, a.categories
1227
+ assert_equal type.tags, a.tags
1228
+ assert_equal a.categories, a.tags
1229
+ end
1230
+
1231
+ assert_raise(ApplicationType::NotFound) { ApplicationType.find('blacklist') }
1232
+ end
1233
+
1234
+ def test_application_templates
1235
+ mock_quickstart_disabled
1236
+ ActiveResource::HttpMock.respond_to(false) do |mock|
1237
+ mock.get '/broker/rest/cartridges.json', anonymous_json_header, [
1238
+ ].to_json
1239
+
1240
+ mock.get '/broker/rest/application_templates.json', anonymous_json_header, [
1241
+ {
1242
+ :name => 'blacklist',
1243
+ :tags => [:framework, :blacklist],
1244
+ :metadata => {},
1245
+ :descriptor_yaml => ''
1246
+ },
1247
+ {
1248
+ :name => 'rails',
1249
+ :tags => [:framework, :ruby, :rails, :in_development],
1250
+ :descriptor_yaml => YAML.dump({
1251
+ 'Name' => "rails"
1252
+ }),
1253
+ :metadata => {
1254
+ :attributes => {
1255
+ }.to_json
1256
+ },
1257
+ :display_name => "Ruby on Rails",
1258
+ :uuid => '1234'
1259
+ }
1260
+ ].to_json
1261
+ end
1262
+
1263
+ types = ApplicationType.find :all
1264
+ assert_equal 1, types.length
1265
+
1266
+ assert_equal 'Ruby on Rails', types[0].display_name
1267
+
1268
+ types.each do |type|
1269
+ assert a = ApplicationType.find(type.id)
1270
+ assert_equal type.id, a.id
1271
+ assert_equal type.description, a.description
1272
+ assert_equal type.categories, a.categories
1273
+ end
1274
+
1275
+ assert_raise(ApplicationType::NotFound) { ApplicationType.find('blacklist') }
1276
+
1277
+ # template is in_development and excluded
1278
+ Rails.env.expects(:production?).returns(true)
1279
+ assert ApplicationType.find(:all).empty?
1280
+ end
1281
+
1282
+ def test_application_job_url
1283
+ a = Application.new :build_job_url => "https://test/test"
1284
+ assert_equal 'https://test/test', a.build_job_url
1285
+ assert !a.builds?
1286
+
1287
+ a = Application.new :building_with => "jenkins-client-1.4"
1288
+ assert_equal 'jenkins-client-1.4', a.building_with
1289
+ assert a.builds?
1290
+
1291
+ a = Application.new :embedded => {}
1292
+ assert_nil a.build_job_url
1293
+ assert !a.builds?
1294
+
1295
+ a = Application.new
1296
+ assert_nil a.build_job_url
1297
+ assert !a.builds?
1298
+ end
1299
+
1300
+ def mock_complex_scaling_cartridges
1301
+ ActiveResource::HttpMock.respond_to do |mock|
1302
+ mock.get '/broker/rest/domains/test/applications/test/cartridges.json', json_header, [
1303
+ {
1304
+ :name => 'mysql-5.1',
1305
+ :collocated_with => [],
1306
+ :scales_from => 1,
1307
+ :scales_to => 1,
1308
+ :current_scale => 1,
1309
+ :supported_scales_from => 1,
1310
+ :supported_scales_to => 1,
1311
+ },
1312
+ {
1313
+ :name => 'haproxy-1.4',
1314
+ :collocated_with => ['php-5.3'],
1315
+ :scales_from => 1,
1316
+ :scales_to => 1,
1317
+ :current_scale => 1,
1318
+ :supported_scales_from => 1,
1319
+ :supported_scales_to => 1,
1320
+ },
1321
+ {
1322
+ :name => 'php-5.3',
1323
+ :collocated_with => ['haproxy-1.4'],
1324
+ :scales_from => 1,
1325
+ :scales_to => 5,
1326
+ :current_scale => 3,
1327
+ :supported_scales_from => 1,
1328
+ :supported_scales_to => 6,
1329
+ :scales_with => 'haproxy-1.4',
1330
+ },
1331
+ ].to_json
1332
+ end
1333
+ end
1334
+
1335
+ def test_infer_cartridge_groups
1336
+ mock_complex_scaling_cartridges
1337
+ mock_types
1338
+
1339
+ app = Application.new({:name => 'test', :domain_id => 'test', :git_url => 'http://localhost', :ssh_url => 'ssh://a@foo.com', :as => @user}, true)
1340
+ assert groups = app.cartridge_gear_groups
1341
+ assert_equal 2, groups.length
1342
+ assert_equal 1, groups.first.cartridges.length
1343
+ assert_equal 1, groups[1].cartridges.length
1344
+
1345
+ assert php = groups.first.cartridges.first
1346
+ assert_equal 'php-5.3', php.name
1347
+ assert_equal [true, 1, 3, 5],
1348
+ [:scales?, :scales_from, :current_scale, :scales_to].map{ |s| php.send(s) }
1349
+
1350
+ assert_equal app.git_url, php.git_url
1351
+ assert_equal app.ssh_url, php.ssh_url
1352
+ assert_equal app.ssh_string, php.ssh_string
1353
+
1354
+ assert mysql = groups[1].cartridges.first
1355
+ assert_equal 'mysql-5.1', mysql.name
1356
+ assert_equal [false, 1, 1, 1],
1357
+ [:scales?, :scales_from, :current_scale, :scales_to].map{ |s| mysql.send(s) }
1358
+ end
1359
+
1360
+ def mock_complex_scaling_gear_group
1361
+ ActiveResource::HttpMock.respond_to do |mock|
1362
+ mock.get '/broker/rest/domains/test/applications/test/gear_groups.json', json_header, [
1363
+ {:name => '@@app/comp-web/php-5.3', :gears => [
1364
+ {:id => 1, :state => 'started'}
1365
+ ], :cartridges => [
1366
+ {:name => 'php-5.3'},
1367
+ ]},
1368
+ {:name => '@@app/comp-proxy/php-5.3', :gears => [
1369
+ {:id => 2, :state => 'started'},
1370
+ ], :cartridges => [
1371
+ {:name => 'php-5.3'},
1372
+ {:name => 'haproxy-1.4'},
1373
+ ]},
1374
+ {:name => '@@app/comp-mysql/mysql-5.0', :gears => [
1375
+ {:id => 3, :state => 'started'},
1376
+ ], :cartridges => [
1377
+ {:name => 'my-sql-5.0'},
1378
+ ]},
1379
+ ].to_json
1380
+ end
1381
+ end
1382
+
1383
+ def test_cartridge_buildable
1384
+ t = CartridgeType.new :name => 'test', :tags => []
1385
+ c = Cartridge.new :name => 'test', :as => @user
1386
+ c.instance_variable_set(:@cartridge_type, t)
1387
+ assert !c.buildable?
1388
+ t.tags.push(:web_framework)
1389
+ assert !c.buildable?
1390
+ c.git_url = 'https://localhost'
1391
+ assert c.buildable?
1392
+ t.tags.clear
1393
+ assert !c.buildable?
1394
+ end
1395
+
1396
+ def test_gear_group_move_features
1397
+ mock_types
1398
+
1399
+ gear1 = Gear.new :id => 1, :state => 'started'
1400
+ cart_build = Cartridge.new :name => 'jenkins-client-1.4'
1401
+ cart_web = Cartridge.new :name => 'php-5.3'
1402
+ group1 = GearGroup.new({:name => 'group1', :gears => [gear1], :cartridges => [cart_build]}, :as => @user)
1403
+
1404
+ group2 = GearGroup.new(:cartridges => [cart_web])
1405
+
1406
+ assert !group1.send(:move_features, group1)
1407
+
1408
+ assert group1.send(:move_features, group2)
1409
+ assert group1.gears.empty?
1410
+ assert group1.cartridges.empty?
1411
+ assert_equal 1, group2.gears.length
1412
+ assert group2.cartridges[0].builds?
1413
+ assert group2.cartridges[0].builds
1414
+ assert_equal cart_build, group2.cartridges[0].builds.with
1415
+ assert_equal group1.name, group2.cartridges[0].builds.on
1416
+
1417
+ assert group1.send(:move_features, group2) # nothing is moved, but group1 is still empty and should be purged
1418
+ end
1419
+
1420
+ def a_quickstart
1421
+ quickstart = {data:[
1422
+ {quickstart:{
1423
+ body:"<p>An awesome blog hosting platform with a rich ecosystem<\/p>",
1424
+ summary:"An awesome blog hosting platform with a rich ecosystem",
1425
+ id:"12069",
1426
+ href:"\/community\/content\/wordpress-34",
1427
+ name:"Wordpress 3.4",
1428
+ updated:"1351538972",
1429
+ cartridges:"php-5.3, mysql-5.1",
1430
+ initial_git_url:"https:\/\/github.com\/openshift\/wordpress-example",
1431
+ language:"PHP",
1432
+ tags:"blog, instant_app, php, wordpress",
1433
+ website:"https:\/\/www.wordpress.org"
1434
+ }}
1435
+ ]}
1436
+ end
1437
+
1438
+ def mock_quickstart
1439
+ Quickstart.reset!
1440
+ RestApi.reset!
1441
+
1442
+ quickstart = a_quickstart
1443
+
1444
+ ActiveResource::HttpMock.respond_to do |mock|
1445
+ mock.get '/broker/rest/api.json', anonymous_json_header, {:data => {
1446
+ 'LIST_QUICKSTARTS' => {'href' => 'https://localhost/community/api/v1/quickstarts/promoted.json'},
1447
+ 'SHOW_QUICKSTART' => {'href' => 'https://localhost/community/api/v1/quickstart/:id'},
1448
+ }}.to_json
1449
+ mock.get('/community/api/v1/quickstarts/promoted.json', anonymous_json_header, quickstart.to_json)
1450
+ mock.get '/community/api/v1/quickstart/12069', anonymous_json_header, quickstart.to_json
1451
+ end
1452
+ end
1453
+
1454
+ def mock_quickstart_search
1455
+ quickstart = a_quickstart
1456
+ ActiveResource::HttpMock.respond_to do |mock|
1457
+ mock.get '/broker/rest/api.json', anonymous_json_header, {:data => {
1458
+ 'LIST_QUICKSTARTS' => {'href' => 'https://localhost/community/api/v1/quickstarts/promoted.json'},
1459
+ 'SHOW_QUICKSTART' => {'href' => 'https://localhost/community/api/v1/quickstart/:id'},
1460
+ 'SEARCH_QUICKSTARTS' => {'href' => 'https://localhost/arbitrary_url/search.json', :required_params => [:name => 'search']},
1461
+ }}.to_json
1462
+ mock.get('/community/api/v1/quickstarts/promoted.json', anonymous_json_header, quickstart.to_json)
1463
+ mock.get '/community/api/v1/quickstart/12069', anonymous_json_header, quickstart.to_json
1464
+ mock.get('/arbitrary_url/search.json?search=bar', anonymous_json_header, {:data => []}.to_json)
1465
+ mock.get('/arbitrary_url/search.json?search=word', anonymous_json_header, quickstart.to_json)
1466
+ end
1467
+ end
1468
+
1469
+ def test_quickstart_caching
1470
+ mock_quickstart_search
1471
+ Quickstart.reset!
1472
+ RestApi.reset!
1473
+ assert_not_equal Quickstart.cached.promoted, Quickstart.cached.search('bar')
1474
+ end
1475
+
1476
+ def test_quickstart
1477
+ assert_equal [:test], Quickstart.new(:tags => ['test']).tags
1478
+
1479
+ assert_equal 'php-5.3', Quickstart.new(:cartridges => 'php-5.3').cartridges_spec
1480
+ assert_equal '"', Quickstart.new(:cartridges => '&quot;').cartridges_spec
1481
+ assert_equal '"', Quickstart.new(:cartridges => '&quot;').cartridges_spec
1482
+
1483
+ assert_equal '"', Quickstart.new(:name => '&quot;').display_name
1484
+ end
1485
+
1486
+ def test_application_type_cartridge_specs
1487
+ assert_equal ['php-5.3'], ApplicationType.new(:cartridges_spec => 'php-5.3').cartridge_specs
1488
+ assert_equal ['php-5.3'], ApplicationType.new(:cartridges => ['php-5.3']).cartridge_specs
1489
+ assert_equal ['php-5.3'], ApplicationType.new(:cartridges => 'php-5.3').cartridge_specs
1490
+ assert_equal ['php-5.3'], ApplicationType.new(:cartridges_spec => ['php-5.3'].to_json).cartridge_specs
1491
+ assert_equal [], ApplicationType.new(:cartridges_spec => nil).cartridge_specs
1492
+ assert_equal [], ApplicationType.new(:cartridges_spec => []).cartridge_specs
1493
+ assert_equal [], ApplicationType.new(:cartridges_spec => '').cartridge_specs
1494
+ assert_raise(ApplicationType::CartridgeSpecInvalid){ ApplicationType.new(:cartridges_spec => "[{").cartridge_specs }
1495
+ assert_raise(ApplicationType::CartridgeSpecInvalid){ ApplicationType.new(:cartridges_spec => '[{name:"php"}]').cartridge_specs }
1496
+ end
1497
+
1498
+ def test_quickstart_search
1499
+ mock_quickstart_search
1500
+ Quickstart.reset!
1501
+ RestApi.reset!
1502
+
1503
+ assert_equal 'search', Quickstart.send(:api_links)[:search_param]
1504
+ assert Quickstart.send(:api_links)[:search].ends_with?('/search.json')
1505
+
1506
+ Quickstart.expects(:promoted).never
1507
+
1508
+ assert_equal [], Quickstart.search('bar')
1509
+ assert_equal 1, Quickstart.search('word').length
1510
+ assert_equal '12069', Quickstart.search('word').first.id
1511
+ end
1512
+
1513
+ def mock_quickstart_disabled
1514
+ Quickstart.reset!
1515
+ RestApi.reset!
1516
+ ActiveResource::HttpMock.respond_to do |mock|
1517
+ mock.get '/broker/rest/api.json', anonymous_json_header, {:data => {}}.to_json
1518
+ end
1519
+ end
1520
+
1521
+ def test_quickstarts
1522
+ mock_quickstart
1523
+
1524
+ assert_equal 1, Quickstart.promoted.length
1525
+ assert q = Quickstart.promoted.first
1526
+ assert_equal "Wordpress 3.4", q.name
1527
+ assert_equal "12069", q.id
1528
+ assert q.website
1529
+ assert_equal 'php-5.3, mysql-5.1', q.cartridges_spec
1530
+ assert q.initial_git_url
1531
+ assert q.tags.include?(:blog)
1532
+ assert q.updated > 1.year.ago
1533
+ end
1534
+
1535
+ def test_quickstart_disabled
1536
+ mock_quickstart_disabled
1537
+ assert Quickstart.disabled?
1538
+ assert_equal [], Quickstart.promoted
1539
+ assert_equal [], Quickstart.search('foo')
1540
+
1541
+ Quickstart.expects(:promoted).at_least_once.returns([Quickstart.new(:summary => 'a', :name => 'b', :tags => 'c')])
1542
+ ['a', 'A', 'b', 'B', 'c', 'C'].each do |s|
1543
+ assert Quickstart.search(s).first, s
1544
+ end
1545
+ assert Quickstart.search('d').empty?
1546
+ assert Quickstart.search('D').empty?
1547
+ end
1548
+
1549
+ def test_quickstart_tags
1550
+ assert Quickstart.new(:tags => ApplicationType::PROTECTED_TAGS.join(', ')).tags.empty?
1551
+ assert_equal ApplicationType::PROTECTED_TAGS, Quickstart.new(:admin_tags => ApplicationType::PROTECTED_TAGS.join(', ')).tags
1552
+ assert_equal [:test] + ApplicationType::PROTECTED_TAGS, Quickstart.new(:tags => 'new, test', :admin_tags => ApplicationType::PROTECTED_TAGS.join(', ')).tags
1553
+ end
1554
+
1555
+ def fixture_cartridges
1556
+ @@cart ||= ActiveSupport::JSON.decode(IO.read(File.expand_path('../../fixtures/cartridges.json', __FILE__)))
1557
+ end
1558
+
1559
+ #
1560
+ # Prime the cartridge type cache so lookups are valid. Call after
1561
+ # HttpMock.respond_to or use respond_to(false).
1562
+ #
1563
+ def mock_types(extra=[])
1564
+ types = extra.concat(fixture_cartridges)
1565
+ ActiveResource::HttpMock.respond_to(false) do |mock|
1566
+ mock.get '/broker/rest/cartridges.json', anonymous_json_header, types.to_json
1567
+ end
1568
+ types = CartridgeType.cached.all
1569
+ assert types.length > 0
1570
+ assert Rails.cache.read(CartridgeType.send(:cache_key_for, :find_every))
1571
+ types
1572
+ end
1573
+
1574
+ def test_destroy_build_cartridge
1575
+ app = Application.new({:domain_id => 'foo', :as => @as, :name => 'me', :building_with => 'jenkins-client-0.0'}, true)
1576
+ Cartridge.any_instance.expects(:destroy).returns(true)
1577
+ assert app.destroy_build_cartridge
1578
+ end
1579
+
1580
+ def test_destroy_build_cartridge_not_building
1581
+ app = Application.new({:domain_id => 'foo', :as => @as, :name => 'me'}, true)
1582
+ assert app.destroy_build_cartridge
1583
+ end
1584
+
1585
+ def test_destroy_build_cartridge_failures
1586
+ app = Application.new({:domain_id => 'foo', :as => @as, :name => 'me', :building_with => 'jenkins-client-0.0'}, true)
1587
+ Cartridge.any_instance.expects(:destroy).raises(ActiveResource::ServerError.new(stub))
1588
+ assert_raise(ActiveResource::ServerError) { app.destroy_build_cartridge }
1589
+ end
1590
+ end