3 class ApplicationControllerTest < ActionController::TestCase
4 # These tests don't do state-changing API calls. Save some time by
5 # skipping the database reset.
6 reset_api_fixtures :after_each_test, false
7 reset_api_fixtures :after_suite, true
10 @user_dataclass = ArvadosBase.resource_class_for_uuid(api_fixture('users')['active']['uuid'])
13 test "links for object" do
16 ac = ApplicationController.new
18 link_head_uuid = api_fixture('links')['foo_file_readable_by_active']['head_uuid']
20 links = ac.send :links_for_object, link_head_uuid
22 assert links, 'Expected links'
23 assert links.is_a?(Array), 'Expected an array'
24 assert links.size > 0, 'Expected at least one link'
25 assert links[0][:uuid], 'Expected uuid for the head_link'
28 test "preload links for objects and uuids" do
31 ac = ApplicationController.new
33 link1_head_uuid = api_fixture('links')['foo_file_readable_by_active']['head_uuid']
34 link2_uuid = api_fixture('links')['bar_file_readable_by_active']['uuid']
35 link3_head_uuid = api_fixture('links')['bar_file_readable_by_active']['head_uuid']
37 link2_object = User.find(api_fixture('users')['active']['uuid'])
38 link2_object_uuid = link2_object['uuid']
40 uuids = [link1_head_uuid, link2_object, link3_head_uuid]
41 links = ac.send :preload_links_for_objects, uuids
43 assert links, 'Expected links'
44 assert links.is_a?(Hash), 'Expected a hash'
45 assert links.size == 3, 'Expected two objects in the preloaded links hash'
46 assert links[link1_head_uuid], 'Expected links for the passed in link head_uuid'
47 assert links[link2_object_uuid], 'Expected links for the passed in object uuid'
48 assert links[link3_head_uuid], 'Expected links for the passed in link head_uuid'
50 # invoke again for this same input. this time, the preloaded data will be returned
51 links = ac.send :preload_links_for_objects, uuids
52 assert links, 'Expected links'
53 assert links.is_a?(Hash), 'Expected a hash'
54 assert links.size == 3, 'Expected two objects in the preloaded links hash'
55 assert links[link1_head_uuid], 'Expected links for the passed in link head_uuid'
58 [ [:preload_links_for_objects, [] ],
59 [:preload_collections_for_objects, [] ],
60 [:preload_log_collections_for_objects, [] ],
61 [:preload_objects_for_dataclass, [] ],
62 [:preload_for_pdhs, [] ],
64 test "preload data for empty array input #{input}" do
67 ac = ApplicationController.new
69 if input[0] == :preload_objects_for_dataclass
70 objects = ac.send input[0], @user_dataclass, input[1]
72 objects = ac.send input[0], input[1]
75 assert objects, 'Expected objects'
76 assert objects.is_a?(Hash), 'Expected a hash'
77 assert objects.size == 0, 'Expected no objects in the preloaded hash'
81 [ [:preload_links_for_objects, 'input not an array'],
82 [:preload_links_for_objects, nil],
83 [:links_for_object, nil],
84 [:preload_collections_for_objects, 'input not an array'],
85 [:preload_collections_for_objects, nil],
86 [:collections_for_object, nil],
87 [:preload_log_collections_for_objects, 'input not an array'],
88 [:preload_log_collections_for_objects, nil],
89 [:log_collections_for_object, nil],
90 [:preload_objects_for_dataclass, 'input not an array'],
91 [:preload_objects_for_dataclass, nil],
92 [:object_for_dataclass, 'some_dataclass', nil],
93 [:object_for_dataclass, nil, 'some_uuid'],
94 [:preload_for_pdhs, 'input not an array'],
95 [:preload_for_pdhs, nil],
97 test "preload data for wrong type input #{input}" do
100 ac = ApplicationController.new
102 if input[0] == :object_for_dataclass
103 assert_raise ArgumentError do
104 ac.send input[0], input[1], input[2]
107 assert_raise ArgumentError do
108 ac.send input[0], input[1]
114 [ [:links_for_object, 'no-such-uuid' ],
115 [:collections_for_object, 'no-such-uuid' ],
116 [:log_collections_for_object, 'no-such-uuid' ],
117 [:object_for_dataclass, 'no-such-uuid' ],
118 [:collection_for_pdh, 'no-such-pdh' ],
120 test "get data for no such uuid #{input}" do
123 ac = ApplicationController.new
125 if input[0] == :object_for_dataclass
126 object = ac.send input[0], @user_dataclass, input[1]
127 assert_not object, 'Expected no object'
129 objects = ac.send input[0], input[1]
130 assert objects, 'Expected objects'
131 assert objects.is_a?(Array), 'Expected a array'
137 test "get 10 objects of data class user" do
140 ac = ApplicationController.new
142 objects = ac.send :get_n_objects_of_class, @user_dataclass, 10
144 assert objects, 'Expected objects'
145 assert objects.is_a?(ArvadosResourceList), 'Expected an ArvadosResourceList'
147 first_object = objects.first
148 assert first_object, 'Expected at least one object'
149 assert_equal 'User', first_object.class.name, 'Expected user object'
151 # invoke it again. this time, the preloaded info will be returned
152 objects = ac.send :get_n_objects_of_class, @user_dataclass, 10
153 assert objects, 'Expected objects'
154 assert_equal 'User', objects.first.class.name, 'Expected user object'
159 [@user_dataclass, 0],
160 [@user_dataclass, -1],
161 [@user_dataclass, nil] ].each do |input|
162 test "get_n_objects for incorrect input #{input}" do
165 ac = ApplicationController.new
167 assert_raise ArgumentError do
168 ac.send :get_n_objects_of_class, input[0], input[1]
173 test "collections for object" do
176 ac = ApplicationController.new
178 uuid = api_fixture('collections')['foo_file']['uuid']
180 collections = ac.send :collections_for_object, uuid
182 assert collections, 'Expected collections'
183 assert collections.is_a?(Array), 'Expected an array'
184 assert collections.size == 1, 'Expected one collection object'
185 assert_equal collections[0][:uuid], uuid, 'Expected uuid not found in collections'
188 test "preload collections for given uuids" do
191 ac = ApplicationController.new
193 uuid1 = api_fixture('collections')['foo_file']['uuid']
194 uuid2 = api_fixture('collections')['bar_file']['uuid']
196 uuids = [uuid1, uuid2]
197 collections = ac.send :preload_collections_for_objects, uuids
199 assert collections, 'Expected collection'
200 assert collections.is_a?(Hash), 'Expected a hash'
201 assert collections.size == 2, 'Expected two objects in the preloaded collection hash'
202 assert collections[uuid1], 'Expected collections for the passed in uuid'
203 assert_equal collections[uuid1].size, 1, 'Expected one collection for the passed in uuid'
204 assert collections[uuid2], 'Expected collections for the passed in uuid'
205 assert_equal collections[uuid2].size, 1, 'Expected one collection for the passed in uuid'
207 # invoke again for this same input. this time, the preloaded data will be returned
208 collections = ac.send :preload_collections_for_objects, uuids
209 assert collections, 'Expected collection'
210 assert collections.is_a?(Hash), 'Expected a hash'
211 assert collections.size == 2, 'Expected two objects in the preloaded collection hash'
212 assert collections[uuid1], 'Expected collections for the passed in uuid'
215 test "log collections for object" do
218 ac = ApplicationController.new
220 uuid = api_fixture('logs')['system_adds_foo_file']['object_uuid']
222 collections = ac.send :log_collections_for_object, uuid
224 assert collections, 'Expected collections'
225 assert collections.is_a?(Array), 'Expected an array'
226 assert collections.size == 1, 'Expected one collection object'
227 assert_equal collections[0][:uuid], uuid, 'Expected uuid not found in collections'
230 test "preload log collections for given uuids" do
233 ac = ApplicationController.new
235 uuid1 = api_fixture('logs')['system_adds_foo_file']['object_uuid']
236 uuid2 = api_fixture('collections')['bar_file']['uuid']
238 uuids = [uuid1, uuid2]
239 collections = ac.send :preload_log_collections_for_objects, uuids
241 assert collections, 'Expected collection'
242 assert collections.is_a?(Hash), 'Expected a hash'
243 assert collections.size == 2, 'Expected two objects in the preloaded collection hash'
244 assert collections[uuid1], 'Expected collections for the passed in uuid'
245 assert_equal collections[uuid1].size, 1, 'Expected one collection for the passed in uuid'
246 assert collections[uuid2], 'Expected collections for the passed in uuid'
247 assert_equal collections[uuid2].size, 1, 'Expected one collection for the passed in uuid'
249 # invoke again for this same input. this time, the preloaded data will be returned
250 collections = ac.send :preload_log_collections_for_objects, uuids
251 assert collections, 'Expected collection'
252 assert collections.is_a?(Hash), 'Expected a hash'
253 assert collections.size == 2, 'Expected two objects in the preloaded collection hash'
254 assert collections[uuid1], 'Expected collections for the passed in uuid'
257 test "object for dataclass" do
260 ac = ApplicationController.new
262 dataclass = ArvadosBase.resource_class_for_uuid(api_fixture('jobs')['running']['uuid'])
263 uuid = api_fixture('jobs')['running']['uuid']
265 obj = ac.send :object_for_dataclass, dataclass, uuid
267 assert obj, 'Expected object'
268 assert 'Job', obj.class
269 assert_equal uuid, obj['uuid'], 'Expected uuid not found'
270 assert_equal api_fixture('jobs')['running']['script_version'], obj['script_version'],
271 'Expected script_version not found'
274 test "preload objects for dataclass" do
277 ac = ApplicationController.new
279 dataclass = ArvadosBase.resource_class_for_uuid(api_fixture('jobs')['running']['uuid'])
281 uuid1 = api_fixture('jobs')['running']['uuid']
282 uuid2 = api_fixture('jobs')['running_cancelled']['uuid']
284 uuids = [uuid1, uuid2]
285 users = ac.send :preload_objects_for_dataclass, dataclass, uuids
287 assert users, 'Expected objects'
288 assert users.is_a?(Hash), 'Expected a hash'
290 assert users.size == 2, 'Expected two objects in the preloaded hash'
291 assert users[uuid1], 'Expected user object for the passed in uuid'
292 assert users[uuid2], 'Expected user object for the passed in uuid'
294 # invoke again for this same input. this time, the preloaded data will be returned
295 users = ac.send :preload_objects_for_dataclass, dataclass, uuids
296 assert users, 'Expected objects'
297 assert users.is_a?(Hash), 'Expected a hash'
298 assert users.size == 2, 'Expected two objects in the preloaded hash'
300 # invoke again for this with one more uuid
301 uuids << api_fixture('jobs')['foobar']['uuid']
302 users = ac.send :preload_objects_for_dataclass, dataclass, uuids
303 assert users, 'Expected objects'
304 assert users.is_a?(Hash), 'Expected a hash'
305 assert users.size == 3, 'Expected two objects in the preloaded hash'
308 test "preload one collection each for given portable_data_hash list" do
311 ac = ApplicationController.new
313 pdh1 = api_fixture('collections')['foo_file']['portable_data_hash']
314 pdh2 = api_fixture('collections')['bar_file']['portable_data_hash']
317 collections = ac.send :preload_for_pdhs, pdhs
319 assert collections, 'Expected collections map'
320 assert collections.is_a?(Hash), 'Expected a hash'
321 # Each pdh has more than one collection; however, we should get only one for each
322 assert collections.size == 2, 'Expected two objects in the preloaded collection hash'
323 assert collections[pdh1], 'Expected collections for the passed in pdh #{pdh1}'
324 assert_equal collections[pdh1].size, 1, 'Expected one collection for the passed in pdh #{pdh1}'
325 assert collections[pdh2], 'Expected collections for the passed in pdh #{pdh2}'
326 assert_equal collections[pdh2].size, 1, 'Expected one collection for the passed in pdh #{pdh2}'
329 test "requesting a nonexistent object returns 404" do
330 # We're really testing ApplicationController's find_object_by_uuid.
331 # It's easiest to do that by instantiating a concrete controller.
332 @controller = NodesController.new
333 get(:show, {id: "zzzzz-zzzzz-zzzzzzzzzzzzzzz"}, session_for(:admin))
337 test "requesting to the API server includes client_session_id param" do
340 stub_api_client.stubs(:post).with do |url, query, opts={}|
343 end.returns fake_api_response('{}', 200, {})
345 Rails.configuration.anonymous_user_token =
346 api_fixture("api_client_authorizations", "anonymous", "api_token")
347 @controller = ProjectsController.new
348 test_uuid = "zzzzz-j7d0g-zzzzzzzzzzzzzzz"
349 get(:show, {id: test_uuid})
351 assert_includes got_query, 'current_request_id'
352 assert_match /\d{10}-\d{9}/, got_query['current_request_id']
355 test "current_request_id is nil after a request" do
356 @controller = NodesController.new
357 get(:index, {}, session_for(:active))
358 assert_nil Thread.current[:current_request_id]
361 [".navbar .login-menu a",
362 ".navbar .login-menu .dropdown-menu a"
363 ].each do |css_selector|
364 test "login link at #{css_selector.inspect} includes return_to param" do
365 # Without an anonymous token, we're immediately redirected to login.
366 Rails.configuration.anonymous_user_token =
367 api_fixture("api_client_authorizations", "anonymous", "api_token")
368 @controller = ProjectsController.new
369 test_uuid = "zzzzz-j7d0g-zzzzzzzzzzzzzzz"
370 get(:show, {id: test_uuid})
371 login_link = css_select(css_selector).first
372 assert_not_nil(login_link, "failed to select login link")
373 login_href = URI.unescape(login_link.attributes["href"])
374 # The parameter needs to include the full URL to work.
375 assert_includes(login_href, "://")
376 assert_match(/[\?&]return_to=[^&]*\/projects\/#{test_uuid}(&|$)/,
381 test "Workbench returns 4xx when API server is unreachable" do
382 # We're really testing ApplicationController's render_exception.
383 # Our primary concern is that it doesn't raise an error and
385 orig_api_server = Rails.configuration.arvados_v1_base
387 # The URL should look valid in all respects, and avoid talking over a
388 # network. 100::/64 is the IPv6 discard prefix, so it's perfect.
389 Rails.configuration.arvados_v1_base = "https://[100::f]:1/"
390 @controller = NodesController.new
391 get(:index, {}, session_for(:active))
392 assert_includes(405..422, @response.code.to_i,
393 "bad response code when API server is unreachable")
395 Rails.configuration.arvados_v1_base = orig_api_server
400 [CollectionsController.new, api_fixture('collections')['user_agreement_in_anonymously_accessible_project']],
401 [CollectionsController.new, api_fixture('collections')['user_agreement_in_anonymously_accessible_project'], false],
402 [JobsController.new, api_fixture('jobs')['running_job_in_publicly_accessible_project']],
403 [JobsController.new, api_fixture('jobs')['running_job_in_publicly_accessible_project'], false],
404 [PipelineInstancesController.new, api_fixture('pipeline_instances')['pipeline_in_publicly_accessible_project']],
405 [PipelineInstancesController.new, api_fixture('pipeline_instances')['pipeline_in_publicly_accessible_project'], false],
406 [PipelineTemplatesController.new, api_fixture('pipeline_templates')['pipeline_template_in_publicly_accessible_project']],
407 [PipelineTemplatesController.new, api_fixture('pipeline_templates')['pipeline_template_in_publicly_accessible_project'], false],
408 [ProjectsController.new, api_fixture('groups')['anonymously_accessible_project']],
409 [ProjectsController.new, api_fixture('groups')['anonymously_accessible_project'], false],
410 ].each do |controller, fixture, anon_config=true|
411 test "#{controller} show method with anonymous config #{anon_config ? '' : 'not '}enabled" do
413 Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
415 Rails.configuration.anonymous_user_token = false
418 @controller = controller
420 get(:show, {id: fixture['uuid']})
424 if controller.class == JobsController
425 assert_includes @response.inspect, fixture['script']
427 assert_includes @response.inspect, fixture['name']
430 assert_response :redirect
431 assert_match /\/users\/welcome/, @response.redirect_url
440 test "invoke show with include_accept_encoding_header config #{config}" do
441 Rails.configuration.include_accept_encoding_header_in_api_requests = config
443 @controller = CollectionsController.new
444 get(:show, {id: api_fixture('collections')['foo_file']['uuid']}, session_for(:admin))
446 assert_equal([['.', 'foo', 3]], assigns(:object).files)
450 test 'Edit name and verify that a duplicate is not created' do
451 @controller = ProjectsController.new
452 project = api_fixture("groups")["aproject"]
459 }, session_for(:active)
460 assert_includes @response.body, 'test name'
461 updated = assigns(:object)
462 assert_equal updated.uuid, project["uuid"]
463 assert_equal 'test name', updated.name
467 [VirtualMachinesController.new, 'hostname', false],
468 [UsersController.new, 'first_name', true],
469 ].each do |controller, expect_str, expect_home_link|
470 test "access #{controller.controller_name} index as admin and verify Home link is#{' not' if !expect_home_link} shown" do
471 @controller = controller
473 get :index, {}, session_for(:admin)
476 assert_includes @response.body, expect_str
478 home_link = "/projects/#{api_fixture('users')['active']['uuid']}"
481 refute_empty css_select("[href=\"/projects/#{api_fixture('users')['active']['uuid']}\"]")
483 assert_empty css_select("[href=\"/projects/#{api_fixture('users')['active']['uuid']}\"]")
489 [VirtualMachinesController.new, 'hostname', true],
490 [UsersController.new, 'first_name', false],
491 ].each do |controller, expect_str, expect_delete_link|
492 test "access #{controller.controller_name} index as admin and verify Delete option is#{' not' if !expect_delete_link} shown" do
493 @controller = controller
495 get :index, {}, session_for(:admin)
498 assert_includes @response.body, expect_str
499 if expect_delete_link
500 refute_empty css_select('[data-method=delete]')
502 assert_empty css_select('[data-method=delete]')