3960: Merge branch 'master' into 3960-show-more-repos
[arvados.git] / apps / workbench / test / functional / application_controller_test.rb
1 require 'test_helper'
2
3 class ApplicationControllerTest < ActionController::TestCase
4
5   setup do
6     @user_dataclass = ArvadosBase.resource_class_for_uuid(api_fixture('users')['active']['uuid'])
7   end
8
9   test "links for object" do
10     use_token :active
11
12     ac = ApplicationController.new
13
14     link_head_uuid = api_fixture('links')['foo_file_readable_by_active']['head_uuid']
15
16     links = ac.send :links_for_object, link_head_uuid
17
18     assert links, 'Expected links'
19     assert links.is_a?(Array), 'Expected an array'
20     assert links.size > 0, 'Expected at least one link'
21     assert links[0][:uuid], 'Expected uuid for the head_link'
22   end
23
24   test "preload links for objects and uuids" do
25     use_token :active
26
27     ac = ApplicationController.new
28
29     link1_head_uuid = api_fixture('links')['foo_file_readable_by_active']['head_uuid']
30     link2_uuid = api_fixture('links')['bar_file_readable_by_active']['uuid']
31     link3_head_uuid = api_fixture('links')['bar_file_readable_by_active']['head_uuid']
32
33     link2_object = User.find(api_fixture('users')['active']['uuid'])
34     link2_object_uuid = link2_object['uuid']
35
36     uuids = [link1_head_uuid, link2_object, link3_head_uuid]
37     links = ac.send :preload_links_for_objects, uuids
38
39     assert links, 'Expected links'
40     assert links.is_a?(Hash), 'Expected a hash'
41     assert links.size == 3, 'Expected two objects in the preloaded links hash'
42     assert links[link1_head_uuid], 'Expected links for the passed in link head_uuid'
43     assert links[link2_object_uuid], 'Expected links for the passed in object uuid'
44     assert links[link3_head_uuid], 'Expected links for the passed in link head_uuid'
45
46     # invoke again for this same input. this time, the preloaded data will be returned
47     links = ac.send :preload_links_for_objects, uuids
48     assert links, 'Expected links'
49     assert links.is_a?(Hash), 'Expected a hash'
50     assert links.size == 3, 'Expected two objects in the preloaded links hash'
51     assert links[link1_head_uuid], 'Expected links for the passed in link head_uuid'
52   end
53
54   [ [:preload_links_for_objects, [] ],
55     [:preload_collections_for_objects, [] ],
56     [:preload_log_collections_for_objects, [] ],
57     [:preload_objects_for_dataclass, [] ],
58   ].each do |input|
59     test "preload data for empty array input #{input}" do
60       use_token :active
61
62       ac = ApplicationController.new
63
64       if input[0] == :preload_objects_for_dataclass
65         objects = ac.send input[0], @user_dataclass, input[1]
66       else
67         objects = ac.send input[0], input[1]
68       end
69
70       assert objects, 'Expected objects'
71       assert objects.is_a?(Hash), 'Expected a hash'
72       assert objects.size == 0, 'Expected no objects in the preloaded hash'
73     end
74   end
75
76   [ [:preload_links_for_objects, 'input not an array'],
77     [:preload_links_for_objects, nil],
78     [:links_for_object, nil],
79     [:preload_collections_for_objects, 'input not an array'],
80     [:preload_collections_for_objects, nil],
81     [:collections_for_object, nil],
82     [:preload_log_collections_for_objects, 'input not an array'],
83     [:preload_log_collections_for_objects, nil],
84     [:log_collections_for_object, nil],
85     [:preload_objects_for_dataclass, 'input not an array'],
86     [:preload_objects_for_dataclass, nil],
87     [:object_for_dataclass, 'some_dataclass', nil],
88     [:object_for_dataclass, nil, 'some_uuid'],
89   ].each do |input|
90     test "preload data for wrong type input #{input}" do
91       use_token :active
92
93       ac = ApplicationController.new
94
95       if input[0] == :object_for_dataclass
96         assert_raise ArgumentError do
97           ac.send input[0], input[1], input[2]
98         end
99       else
100         assert_raise ArgumentError do
101           ac.send input[0], input[1]
102         end
103       end
104     end
105   end
106
107   [ [:links_for_object, 'no-such-uuid' ],
108     [:collections_for_object, 'no-such-uuid' ],
109     [:log_collections_for_object, 'no-such-uuid' ],
110     [:object_for_dataclass, 'no-such-uuid' ],
111   ].each do |input|
112     test "get data for no such uuid #{input}" do
113       use_token :active
114
115       ac = ApplicationController.new
116
117       if input[0] == :object_for_dataclass
118         object = ac.send input[0], @user_dataclass, input[1]
119         assert_not object, 'Expected no object'
120       else
121         objects = ac.send input[0], input[1]
122         assert objects, 'Expected objects'
123         assert objects.is_a?(Array), 'Expected a array'
124       end
125     end
126   end
127
128   test "get 10 objects of data class user" do
129     use_token :active
130
131     ac = ApplicationController.new
132
133     objects = ac.send :get_n_objects_of_class, @user_dataclass, 10
134
135     assert objects, 'Expected objects'
136     assert objects.is_a?(ArvadosResourceList), 'Expected an ArvadosResourceList'
137
138     first_object = objects.first
139     assert first_object, 'Expected at least one object'
140     assert_equal 'User', first_object.class.name, 'Expected user object'
141
142     # invoke it again. this time, the preloaded info will be returned
143     objects = ac.send :get_n_objects_of_class, @user_dataclass, 10
144     assert objects, 'Expected objects'
145     assert_equal 'User', objects.first.class.name, 'Expected user object'
146   end
147
148   [ ['User', 10],
149     [nil, 10],
150     [@user_dataclass, 0],
151     [@user_dataclass, -1],
152     [@user_dataclass, nil] ].each do |input|
153     test "get_n_objects for incorrect input #{input}" do
154       use_token :active
155
156       ac = ApplicationController.new
157
158       assert_raise ArgumentError do
159         ac.send :get_n_objects_of_class, input[0], input[1]
160       end
161     end
162   end
163
164   test "collections for object" do
165     use_token :active
166
167     ac = ApplicationController.new
168
169     uuid = api_fixture('collections')['foo_file']['uuid']
170
171     collections = ac.send :collections_for_object, uuid
172
173     assert collections, 'Expected collections'
174     assert collections.is_a?(Array), 'Expected an array'
175     assert collections.size == 1, 'Expected one collection object'
176     assert_equal collections[0][:uuid], uuid, 'Expected uuid not found in collections'
177   end
178
179   test "preload collections for given uuids" do
180     use_token :active
181
182     ac = ApplicationController.new
183
184     uuid1 = api_fixture('collections')['foo_file']['uuid']
185     uuid2 = api_fixture('collections')['bar_file']['uuid']
186
187     uuids = [uuid1, uuid2]
188     collections = ac.send :preload_collections_for_objects, uuids
189
190     assert collections, 'Expected collection'
191     assert collections.is_a?(Hash), 'Expected a hash'
192     assert collections.size == 2, 'Expected two objects in the preloaded collection hash'
193     assert collections[uuid1], 'Expected collections for the passed in uuid'
194     assert_equal collections[uuid1].size, 1, 'Expected one collection for the passed in uuid'
195     assert collections[uuid2], 'Expected collections for the passed in uuid'
196     assert_equal collections[uuid2].size, 1, 'Expected one collection for the passed in uuid'
197
198     # invoke again for this same input. this time, the preloaded data will be returned
199     collections = ac.send :preload_collections_for_objects, uuids
200     assert collections, 'Expected collection'
201     assert collections.is_a?(Hash), 'Expected a hash'
202     assert collections.size == 2, 'Expected two objects in the preloaded collection hash'
203     assert collections[uuid1], 'Expected collections for the passed in uuid'
204   end
205
206   test "log collections for object" do
207     use_token :active
208
209     ac = ApplicationController.new
210
211     uuid = api_fixture('logs')['log4']['object_uuid']
212
213     collections = ac.send :log_collections_for_object, uuid
214
215     assert collections, 'Expected collections'
216     assert collections.is_a?(Array), 'Expected an array'
217     assert collections.size == 1, 'Expected one collection object'
218     assert_equal collections[0][:uuid], uuid, 'Expected uuid not found in collections'
219   end
220
221   test "preload log collections for given uuids" do
222     use_token :active
223
224     ac = ApplicationController.new
225
226     uuid1 = api_fixture('logs')['log4']['object_uuid']
227     uuid2 = api_fixture('collections')['bar_file']['uuid']
228
229     uuids = [uuid1, uuid2]
230     collections = ac.send :preload_log_collections_for_objects, uuids
231
232     assert collections, 'Expected collection'
233     assert collections.is_a?(Hash), 'Expected a hash'
234     assert collections.size == 2, 'Expected two objects in the preloaded collection hash'
235     assert collections[uuid1], 'Expected collections for the passed in uuid'
236     assert_equal collections[uuid1].size, 1, 'Expected one collection for the passed in uuid'
237     assert collections[uuid2], 'Expected collections for the passed in uuid'
238     assert_equal collections[uuid2].size, 1, 'Expected one collection for the passed in uuid'
239
240     # invoke again for this same input. this time, the preloaded data will be returned
241     collections = ac.send :preload_log_collections_for_objects, uuids
242     assert collections, 'Expected collection'
243     assert collections.is_a?(Hash), 'Expected a hash'
244     assert collections.size == 2, 'Expected two objects in the preloaded collection hash'
245     assert collections[uuid1], 'Expected collections for the passed in uuid'
246   end
247
248   test "object for dataclass" do
249     use_token :active
250
251     ac = ApplicationController.new
252
253     dataclass = ArvadosBase.resource_class_for_uuid(api_fixture('jobs')['running']['uuid'])
254     uuid = api_fixture('jobs')['running']['uuid']
255
256     obj = ac.send :object_for_dataclass, dataclass, uuid
257
258     assert obj, 'Expected object'
259     assert 'Job', obj.class
260     assert_equal uuid, obj['uuid'], 'Expected uuid not found'
261     assert_equal api_fixture('jobs')['running']['script_version'], obj['script_version'],
262       'Expected script_version not found'
263   end
264
265   test "preload objects for dataclass" do
266     use_token :active
267
268     ac = ApplicationController.new
269
270     dataclass = ArvadosBase.resource_class_for_uuid(api_fixture('jobs')['running']['uuid'])
271
272     uuid1 = api_fixture('jobs')['running']['uuid']
273     uuid2 = api_fixture('jobs')['running_cancelled']['uuid']
274
275     uuids = [uuid1, uuid2]
276     users = ac.send :preload_objects_for_dataclass, dataclass, uuids
277
278     assert users, 'Expected objects'
279     assert users.is_a?(Hash), 'Expected a hash'
280
281     assert users.size == 2, 'Expected two objects in the preloaded hash'
282     assert users[uuid1], 'Expected user object for the passed in uuid'
283     assert users[uuid2], 'Expected user object for the passed in uuid'
284
285     # invoke again for this same input. this time, the preloaded data will be returned
286     users = ac.send :preload_objects_for_dataclass, dataclass, uuids
287     assert users, 'Expected objects'
288     assert users.is_a?(Hash), 'Expected a hash'
289     assert users.size == 2, 'Expected two objects in the preloaded hash'
290
291     # invoke again for this with one more uuid
292     uuids << api_fixture('jobs')['foobar']['uuid']
293     users = ac.send :preload_objects_for_dataclass, dataclass, uuids
294     assert users, 'Expected objects'
295     assert users.is_a?(Hash), 'Expected a hash'
296     assert users.size == 3, 'Expected two objects in the preloaded hash'
297   end
298
299   test "requesting a nonexistent object returns 404" do
300     # We're really testing ApplicationController's find_object_by_uuid.
301     # It's easiest to do that by instantiating a concrete controller.
302     @controller = NodesController.new
303     get(:show, {id: "zzzzz-zzzzz-zzzzzzzzzzzzzzz"}, session_for(:admin))
304     assert_response 404
305   end
306
307   test "Workbench returns 4xx when API server is unreachable" do
308     # We're really testing ApplicationController's render_exception.
309     # Our primary concern is that it doesn't raise an error and
310     # return 500.
311     orig_api_server = Rails.configuration.arvados_v1_base
312     begin
313       # The URL should look valid in all respects, and avoid talking over a
314       # network.  100::/64 is the IPv6 discard prefix, so it's perfect.
315       Rails.configuration.arvados_v1_base = "https://[100::f]:1/"
316       @controller = NodesController.new
317       get(:index, {}, session_for(:active))
318       assert_includes(405..422, @response.code.to_i,
319                       "bad response code when API server is unreachable")
320     ensure
321       Rails.configuration.arvados_v1_base = orig_api_server
322     end
323   end
324 end