14873: Modifies failing tests for debugging purposes.
[arvados.git] / services / api / test / functional / arvados / v1 / groups_controller_test.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 require 'test_helper'
6
7 class Arvados::V1::GroupsControllerTest < ActionController::TestCase
8
9   test "attempt to delete group without read or write access" do
10     authorize_with :active
11     post :destroy, params: {id: groups(:empty_lonely_group).uuid}
12     assert_response 404
13   end
14
15   test "attempt to delete group without write access" do
16     authorize_with :active
17     post :destroy, params: {id: groups(:all_users).uuid}
18     assert_response 403
19   end
20
21   test "get list of projects" do
22     authorize_with :active
23     get :index, params: {filters: [['group_class', '=', 'project']], format: :json}
24     assert_response :success
25     group_uuids = []
26     json_response['items'].each do |group|
27       assert_equal 'project', group['group_class']
28       group_uuids << group['uuid']
29     end
30     assert_includes group_uuids, groups(:aproject).uuid
31     assert_includes group_uuids, groups(:asubproject).uuid
32     assert_not_includes group_uuids, groups(:system_group).uuid
33     assert_not_includes group_uuids, groups(:private).uuid
34   end
35
36   test "get list of groups that are not projects" do
37     authorize_with :active
38     get :index, params: {filters: [['group_class', '!=', 'project']], format: :json}
39     assert_response :success
40     group_uuids = []
41     json_response['items'].each do |group|
42       assert_not_equal 'project', group['group_class']
43       group_uuids << group['uuid']
44     end
45     assert_not_includes group_uuids, groups(:aproject).uuid
46     assert_not_includes group_uuids, groups(:asubproject).uuid
47     assert_includes group_uuids, groups(:private).uuid
48     assert_includes group_uuids, groups(:group_with_no_class).uuid
49   end
50
51   test "get list of groups with bogus group_class" do
52     authorize_with :active
53     get :index, params: {
54       filters: [['group_class', '=', 'nogrouphasthislittleclass']],
55       format: :json,
56     }
57     assert_response :success
58     assert_equal [], json_response['items']
59     assert_equal 0, json_response['items_available']
60   end
61
62   def check_project_contents_response disabled_kinds=[]
63     assert_response :success
64     assert_operator 2, :<=, json_response['items_available']
65     assert_operator 2, :<=, json_response['items'].count
66     kinds = json_response['items'].collect { |i| i['kind'] }.uniq
67     expect_kinds = %w'arvados#group arvados#specimen arvados#pipelineTemplate arvados#job' - disabled_kinds
68     assert_equal expect_kinds, (expect_kinds & kinds)
69
70     json_response['items'].each do |i|
71       if i['kind'] == 'arvados#group'
72         assert(i['group_class'] == 'project',
73                "group#contents returned a non-project group")
74       end
75     end
76
77     disabled_kinds.each do |d|
78       assert_equal true, !kinds.include?(d)
79     end
80   end
81
82   test 'get group-owned objects' do
83     authorize_with :active
84     get :contents, params: {
85       id: groups(:aproject).uuid,
86       format: :json,
87     }
88     check_project_contents_response
89   end
90
91   test "user with project read permission can see project objects" do
92     authorize_with :project_viewer
93     get :contents, params: {
94       id: groups(:aproject).uuid,
95       format: :json,
96     }
97     check_project_contents_response
98   end
99
100   test "list objects across projects" do
101     authorize_with :project_viewer
102     get :contents, params: {
103       format: :json,
104       filters: [['uuid', 'is_a', 'arvados#specimen']]
105     }
106     assert_response :success
107     found_uuids = json_response['items'].collect { |i| i['uuid'] }
108     [[:in_aproject, true],
109      [:in_asubproject, true],
110      [:owned_by_private_group, false]].each do |specimen_fixture, should_find|
111       if should_find
112         assert_includes found_uuids, specimens(specimen_fixture).uuid, "did not find specimen fixture '#{specimen_fixture}'"
113       else
114         refute_includes found_uuids, specimens(specimen_fixture).uuid, "found specimen fixture '#{specimen_fixture}'"
115       end
116     end
117   end
118
119   test "list trashed collections and projects" do
120     authorize_with :active
121     get(:contents, params: {
122           format: :json,
123           include_trash: true,
124           filters: [
125             ['uuid', 'is_a', ['arvados#collection', 'arvados#group']],
126             ['is_trashed', '=', true],
127           ],
128           limit: 10000,
129         })
130     assert_response :success
131     found_uuids = json_response['items'].collect { |i| i['uuid'] }
132     assert_includes found_uuids, groups(:trashed_project).uuid
133     refute_includes found_uuids, groups(:aproject).uuid
134     assert_includes found_uuids, collections(:expired_collection).uuid
135     refute_includes found_uuids, collections(:w_a_z_file).uuid
136   end
137
138   test "list objects in home project" do
139     authorize_with :active
140     get :contents, params: {
141       format: :json,
142       limit: 200,
143       id: users(:active).uuid
144     }
145     assert_response :success
146     found_uuids = json_response['items'].collect { |i| i['uuid'] }
147     assert_includes found_uuids, specimens(:owned_by_active_user).uuid, "specimen did not appear in home project"
148     refute_includes found_uuids, specimens(:in_asubproject).uuid, "specimen appeared unexpectedly in home project"
149   end
150
151   test "user with project read permission can see project collections" do
152     authorize_with :project_viewer
153     get :contents, params: {
154       id: groups(:asubproject).uuid,
155       format: :json,
156     }
157     ids = json_response['items'].map { |item| item["uuid"] }
158     assert_includes ids, collections(:baz_file_in_asubproject).uuid
159   end
160
161   [
162     ['collections.name', 'asc', :<=, "name"],
163     ['collections.name', 'desc', :>=, "name"],
164     ['name', 'asc', :<=, "name"],
165     ['name', 'desc', :>=, "name"],
166     ['collections.created_at', 'asc', :<=, "created_at"],
167     ['collections.created_at', 'desc', :>=, "created_at"],
168     ['created_at', 'asc', :<=, "created_at"],
169     ['created_at', 'desc', :>=, "created_at"],
170   ].each do |column, order, operator, field|
171     test "user with project read permission can sort projects on #{column} #{order}" do
172       authorize_with :project_viewer
173       get :contents, params: {
174         id: groups(:asubproject).uuid,
175         format: :json,
176         filters: [['uuid', 'is_a', "arvados#collection"]],
177         order: "#{column} #{order}"
178       }
179       sorted_values = json_response['items'].collect { |item| item[field] }
180       if field == "name"
181         # Here we avoid assuming too much about the database
182         # collation. Both "alice"<"Bob" and "alice">"Bob" can be
183         # correct. Hopefully it _is_ safe to assume that if "a" comes
184         # before "b" in the ascii alphabet, "aX">"bY" is never true for
185         # any strings X and Y.
186         reliably_sortable_names = sorted_values.select do |name|
187           name[0] >= 'a' && name[0] <= 'z'
188         end.uniq do |name|
189           name[0]
190         end
191         # Preserve order of sorted_values. But do not use &=. If
192         # sorted_values has out-of-order duplicates, we want to preserve
193         # them here, so we can detect them and fail the test below.
194         sorted_values.select! do |name|
195           reliably_sortable_names.include? name
196         end
197       end
198       assert_sorted(operator, sorted_values)
199     end
200   end
201
202   def assert_sorted(operator, sorted_items)
203     actually_checked_anything = false
204     previous = nil
205     sorted_items.each do |entry|
206       if !previous.nil?
207         assert_operator(previous, operator, entry,
208                         "Entries sorted incorrectly.")
209         actually_checked_anything = true
210       end
211       previous = entry
212     end
213     assert actually_checked_anything, "Didn't even find two items to compare."
214   end
215
216   # Even though the project_viewer tests go through other controllers,
217   # I'm putting them here so they're easy to find alongside the other
218   # project tests.
219   def check_new_project_link_fails(link_attrs)
220     @controller = Arvados::V1::LinksController.new
221     post :create, params: {
222       link: {
223         link_class: "permission",
224         name: "can_read",
225         head_uuid: groups(:aproject).uuid,
226       }.merge(link_attrs)
227     }
228     assert_includes(403..422, response.status)
229   end
230
231   test "user with project read permission can't add users to it" do
232     authorize_with :project_viewer
233     check_new_project_link_fails(tail_uuid: users(:spectator).uuid)
234   end
235
236   test "user with project read permission can't add items to it" do
237     authorize_with :project_viewer
238     check_new_project_link_fails(tail_uuid: collections(:baz_file).uuid)
239   end
240
241   test "user with project read permission can't rename items in it" do
242     authorize_with :project_viewer
243     @controller = Arvados::V1::LinksController.new
244     post :update, params: {
245       id: jobs(:running).uuid,
246       name: "Denied test name",
247     }
248     assert_includes(403..404, response.status)
249   end
250
251   test "user with project read permission can't remove items from it" do
252     @controller = Arvados::V1::PipelineTemplatesController.new
253     authorize_with :project_viewer
254     post :update, params: {
255       id: pipeline_templates(:two_part).uuid,
256       pipeline_template: {
257         owner_uuid: users(:project_viewer).uuid,
258       }
259     }
260     assert_response 403
261   end
262
263   test "user with project read permission can't delete it" do
264     authorize_with :project_viewer
265     post :destroy, params: {id: groups(:aproject).uuid}
266     assert_response 403
267   end
268
269   test 'get group-owned objects with limit' do
270     authorize_with :active
271     get :contents, params: {
272       id: groups(:aproject).uuid,
273       limit: 1,
274       format: :json,
275     }
276     assert_response :success
277     assert_operator 1, :<, json_response['items_available']
278     assert_equal 1, json_response['items'].count
279   end
280
281   test 'get group-owned objects with limit and offset' do
282     authorize_with :active
283     get :contents, params: {
284       id: groups(:aproject).uuid,
285       limit: 1,
286       offset: 12345,
287       format: :json,
288     }
289     assert_response :success
290     assert_operator 1, :<, json_response['items_available']
291     assert_equal 0, json_response['items'].count
292   end
293
294   test 'get group-owned objects with additional filter matching nothing' do
295     authorize_with :active
296     get :contents, params: {
297       id: groups(:aproject).uuid,
298       filters: [['uuid', 'in', ['foo_not_a_uuid','bar_not_a_uuid']]],
299       format: :json,
300     }
301     assert_response :success
302     assert_equal [], json_response['items']
303     assert_equal 0, json_response['items_available']
304   end
305
306   %w(offset limit).each do |arg|
307     ['foo', '', '1234five', '0x10', '-8'].each do |val|
308       test "Raise error on bogus #{arg} parameter #{val.inspect}" do
309         authorize_with :active
310         get :contents, params: {
311           :id => groups(:aproject).uuid,
312           :format => :json,
313           arg => val,
314         }
315         assert_response 422
316       end
317     end
318   end
319
320   test "Collection contents don't include manifest_text" do
321     authorize_with :active
322     get :contents, params: {
323       id: groups(:aproject).uuid,
324       filters: [["uuid", "is_a", "arvados#collection"]],
325       format: :json,
326     }
327     assert_response :success
328     refute(json_response["items"].any? { |c| not c["portable_data_hash"] },
329            "response included an item without a portable data hash")
330     refute(json_response["items"].any? { |c| c.include?("manifest_text") },
331            "response included an item with a manifest text")
332   end
333
334   test 'get writable_by list for owned group' do
335     authorize_with :active
336     get :show, params: {
337       id: groups(:aproject).uuid,
338       format: :json
339     }
340     assert_response :success
341     assert_not_nil(json_response['writable_by'],
342                    "Should receive uuid list in 'writable_by' field")
343     assert_includes(json_response['writable_by'], users(:active).uuid,
344                     "owner should be included in writable_by list")
345   end
346
347   test 'no writable_by list for group with read-only access' do
348     authorize_with :rominiadmin
349     get :show, params: {
350       id: groups(:testusergroup_admins).uuid,
351       format: :json
352     }
353     assert_response :success
354     assert_equal([json_response['owner_uuid']],
355                  json_response['writable_by'],
356                  "Should only see owner_uuid in 'writable_by' field")
357   end
358
359   test 'get writable_by list by admin user' do
360     authorize_with :admin
361     get :show, params: {
362       id: groups(:testusergroup_admins).uuid,
363       format: :json
364     }
365     assert_response :success
366     assert_not_nil(json_response['writable_by'],
367                    "Should receive uuid list in 'writable_by' field")
368     assert_includes(json_response['writable_by'],
369                     users(:admin).uuid,
370                     "Current user should be included in 'writable_by' field")
371   end
372
373   test 'creating subproject with duplicate name fails' do
374     authorize_with :active
375     post :create, params: {
376       group: {
377         name: 'A Project',
378         owner_uuid: users(:active).uuid,
379         group_class: 'project',
380       },
381     }
382     assert_response 422
383     response_errors = json_response['errors']
384     assert_not_nil response_errors, 'Expected error in response'
385     assert(response_errors.first.include?('duplicate key'),
386            "Expected 'duplicate key' error in #{response_errors.first}")
387   end
388
389   test 'creating duplicate named subproject succeeds with ensure_unique_name' do
390     authorize_with :active
391     post :create, params: {
392       group: {
393         name: 'A Project',
394         owner_uuid: users(:active).uuid,
395         group_class: 'project',
396       },
397       ensure_unique_name: true
398     }
399     assert_response :success
400     new_project = json_response
401     assert_not_equal(new_project['uuid'],
402                      groups(:aproject).uuid,
403                      "create returned same uuid as existing project")
404     assert_match(/^A Project \(\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z\)$/,
405                  new_project['name'])
406   end
407
408   test "unsharing a project results in hiding it from previously shared user" do
409     # Make the same call as in line 448.
410     @controller = Arvados::V1::LinksController.new
411     authorize_with :system_user
412     post :create, params: {
413       link: {
414         link_class: "permission",
415         name: "can_read",
416         head_uuid: groups(:starred_and_shared_active_user_project).uuid,
417         tail_uuid: users(:project_viewer).uuid,
418       }
419     }
420     assert_response :success
421     assert_equal 'permission', json_response['link_class']
422     l = Link.find_by_uuid(json_response['uuid'])
423     l.destroy
424     @test_counter = 0
425
426     # remove sharing link for project
427     @controller = Arvados::V1::LinksController.new
428     authorize_with :admin
429     post :destroy, params: {id: links(:share_starred_project_with_project_viewer).uuid}
430     assert_response :success
431
432     # verify that the user can no longer see the project
433     @test_counter = 0  # Reset executed action counter
434     @controller = Arvados::V1::GroupsController.new
435     authorize_with :project_viewer
436     get :index, params: {filters: [['group_class', '=', 'project']], format: :json}
437     assert_response :success
438     found_projects = {}
439     json_response['items'].each do |g|
440       found_projects[g['uuid']] = g
441     end
442     assert_equal false, found_projects.include?(groups(:starred_and_shared_active_user_project).uuid)
443
444     # share the project
445     @test_counter = 0
446     @controller = Arvados::V1::LinksController.new
447     authorize_with :system_user
448     post :create, params: {
449       link: {
450         link_class: "permission",
451         name: "can_read",
452         head_uuid: groups(:starred_and_shared_active_user_project).uuid,
453         tail_uuid: users(:project_viewer).uuid,
454       }
455     }
456     assert_response :success
457     # This fails if the call at the beginning of the test isn't
458     # made, because for some reason the links controller gets
459     # an empty params list.
460     assert_equal 'permission', json_response['link_class']
461     # NOTE that if I manually create the link, the test pass:
462     # Link.create(link_class: 'permission', name: 'can_read', head_uuid: groups(:starred_and_shared_active_user_project).uuid, tail_uuid: users(:project_viewer).uuid)
463
464     # verify that project_viewer user can now see shared project again
465     @test_counter = 0
466     @controller = Arvados::V1::GroupsController.new
467     authorize_with :project_viewer
468     get :index, params: {filters: [['group_class', '=', 'project']], format: :json}
469     assert_response :success
470     found_projects = {}
471     json_response['items'].each do |g|
472       found_projects[g['uuid']] = g
473     end
474     assert_equal true, found_projects.include?(groups(:starred_and_shared_active_user_project).uuid)
475   end
476
477   [
478     [['owner_uuid', '!=', 'zzzzz-tpzed-xurymjxw79nv3jz'], 200,
479         'zzzzz-d1hrv-subprojpipeline', 'zzzzz-d1hrv-1xfj6xkicf2muk2'],
480     [["pipeline_instances.state", "not in", ["Complete", "Failed"]], 200,
481         'zzzzz-d1hrv-1xfj6xkicf2muk2', 'zzzzz-d1hrv-i3e77t9z5y8j9cc'],
482     [['container_requests.requesting_container_uuid', '=', nil], 200,
483         'zzzzz-xvhdp-cr4queuedcontnr', 'zzzzz-xvhdp-cr4requestercn2'],
484     [['container_requests.no_such_column', '=', nil], 422],
485     [['container_requests.', '=', nil], 422],
486     [['.requesting_container_uuid', '=', nil], 422],
487     [['no_such_table.uuid', '!=', 'zzzzz-tpzed-xurymjxw79nv3jz'], 422],
488   ].each do |filter, expect_code, expect_uuid, not_expect_uuid|
489     test "get contents with '#{filter}' filter" do
490       authorize_with :active
491       get :contents, params: {filters: [filter], format: :json}
492       assert_response expect_code
493       if expect_code == 200
494         assert_not_empty json_response['items']
495         item_uuids = json_response['items'].collect {|item| item['uuid']}
496         assert_includes(item_uuids, expect_uuid)
497         assert_not_includes(item_uuids, not_expect_uuid)
498       end
499     end
500   end
501
502   test 'get contents with jobs and pipeline instances disabled' do
503     Rails.configuration.disable_api_methods = ['jobs.index', 'pipeline_instances.index']
504
505     authorize_with :active
506     get :contents, params: {
507       id: groups(:aproject).uuid,
508       format: :json,
509     }
510     check_project_contents_response %w'arvados#pipelineInstance arvados#job'
511   end
512
513   test 'get contents with low max_index_database_read' do
514     # Some result will certainly have at least 12 bytes in a
515     # restricted column
516     Rails.configuration.max_index_database_read = 12
517     authorize_with :active
518     get :contents, params: {
519           id: groups(:aproject).uuid,
520           format: :json,
521         }
522     assert_response :success
523     assert_not_empty(json_response['items'])
524     assert_operator(json_response['items'].count,
525                     :<, json_response['items_available'])
526   end
527
528   test 'get contents, recursive=true' do
529     authorize_with :active
530     params = {
531       id: groups(:aproject).uuid,
532       recursive: true,
533       format: :json,
534     }
535     get :contents, params: params
536     owners = json_response['items'].map do |item|
537       item['owner_uuid']
538     end
539     assert_includes(owners, groups(:aproject).uuid)
540     assert_includes(owners, groups(:asubproject).uuid)
541   end
542
543   [false, nil].each do |recursive|
544     test "get contents, recursive=#{recursive.inspect}" do
545       authorize_with :active
546       params = {
547         id: groups(:aproject).uuid,
548         format: :json,
549       }
550       params[:recursive] = false if recursive == false
551       get :contents, params: params
552       owners = json_response['items'].map do |item|
553         item['owner_uuid']
554       end
555       assert_includes(owners, groups(:aproject).uuid)
556       refute_includes(owners, groups(:asubproject).uuid)
557     end
558   end
559
560   test 'get home project contents, recursive=true' do
561     authorize_with :active
562     get :contents, params: {
563           id: users(:active).uuid,
564           recursive: true,
565           format: :json,
566         }
567     owners = json_response['items'].map do |item|
568       item['owner_uuid']
569     end
570     assert_includes(owners, users(:active).uuid)
571     assert_includes(owners, groups(:aproject).uuid)
572     assert_includes(owners, groups(:asubproject).uuid)
573   end
574
575   ### trashed project tests ###
576
577   [:active, :admin].each do |auth|
578     # project: to query,    to untrash,    is visible, parent contents listing success
579     [[:trashed_project,     [],                 false, true],
580      [:trashed_project,     [:trashed_project], true,  true],
581      [:trashed_subproject,  [],                 false, false],
582      [:trashed_subproject,  [:trashed_project], true,  true],
583      [:trashed_subproject3, [:trashed_project], false, true],
584      [:trashed_subproject3, [:trashed_subproject3], false, false],
585      [:trashed_subproject3, [:trashed_project, :trashed_subproject3], true, true],
586     ].each do |project, untrash, visible, success|
587
588       test "contents listing #{project} #{untrash} as #{auth}" do
589         authorize_with auth
590         untrash.each do |pr|
591           Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
592         end
593         get :contents, params: {
594               id: groups(project).owner_uuid,
595               format: :json
596             }
597         if success
598           assert_response :success
599           item_uuids = json_response['items'].map do |item|
600             item['uuid']
601           end
602           if visible
603             assert_includes(item_uuids, groups(project).uuid)
604           else
605             assert_not_includes(item_uuids, groups(project).uuid)
606           end
607         else
608           assert_response 404
609         end
610       end
611
612       test "contents of #{project} #{untrash} as #{auth}" do
613         authorize_with auth
614         untrash.each do |pr|
615           Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
616         end
617         get :contents, params: {
618               id: groups(project).uuid,
619               format: :json
620             }
621         if visible
622           assert_response :success
623         else
624           assert_response 404
625         end
626       end
627
628       test "index #{project} #{untrash} as #{auth}" do
629         authorize_with auth
630         untrash.each do |pr|
631           Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
632         end
633         get :index, params: {
634               format: :json,
635             }
636         assert_response :success
637         item_uuids = json_response['items'].map do |item|
638           item['uuid']
639         end
640         if visible
641           assert_includes(item_uuids, groups(project).uuid)
642         else
643           assert_not_includes(item_uuids, groups(project).uuid)
644         end
645       end
646
647       test "show #{project} #{untrash} as #{auth}" do
648         authorize_with auth
649         untrash.each do |pr|
650           Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
651         end
652         get :show, params: {
653               id: groups(project).uuid,
654               format: :json
655             }
656         if visible
657           assert_response :success
658         else
659           assert_response 404
660         end
661       end
662
663       test "show include_trash #{project} #{untrash} as #{auth}" do
664         authorize_with auth
665         untrash.each do |pr|
666           Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
667         end
668         get :show, params: {
669               id: groups(project).uuid,
670               format: :json,
671               include_trash: true
672             }
673         assert_response :success
674       end
675
676       test "index include_trash #{project} #{untrash} as #{auth}" do
677         authorize_with auth
678         untrash.each do |pr|
679           Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
680         end
681         get :index, params: {
682               format: :json,
683               include_trash: true
684             }
685         assert_response :success
686         item_uuids = json_response['items'].map do |item|
687           item['uuid']
688         end
689         assert_includes(item_uuids, groups(project).uuid)
690       end
691     end
692
693     test "delete project #{auth}" do
694       authorize_with auth
695       [:trashed_project].each do |pr|
696         Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
697       end
698       assert !Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
699       post :destroy, params: {
700             id: groups(:trashed_project).uuid,
701             format: :json,
702           }
703       assert_response :success
704       assert Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
705     end
706
707     test "untrash project #{auth}" do
708       authorize_with auth
709       assert Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
710       post :untrash, params: {
711             id: groups(:trashed_project).uuid,
712             format: :json,
713           }
714       assert_response :success
715       assert !Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
716     end
717
718     test "untrash project with name conflict #{auth}" do
719       authorize_with auth
720       [:trashed_project].each do |pr|
721         Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
722       end
723       gc = Group.create!({owner_uuid: "zzzzz-j7d0g-trashedproject1",
724                          name: "trashed subproject 3",
725                          group_class: "project"})
726       post :untrash, params: {
727             id: groups(:trashed_subproject3).uuid,
728             format: :json,
729             ensure_unique_name: true
730            }
731       assert_response :success
732       assert_match /^trashed subproject 3 \(\d{4}-\d\d-\d\d.*?Z\)$/, json_response['name']
733     end
734
735     test "move trashed subproject to new owner #{auth}" do
736       authorize_with auth
737       assert_nil Group.readable_by(users(auth)).where(uuid: groups(:trashed_subproject).uuid).first
738       put :update, params: {
739             id: groups(:trashed_subproject).uuid,
740             group: {
741               owner_uuid: users(:active).uuid
742             },
743             include_trash: true,
744             format: :json,
745           }
746       assert_response :success
747       assert_not_nil Group.readable_by(users(auth)).where(uuid: groups(:trashed_subproject).uuid).first
748     end
749   end
750
751   test 'get shared owned by another user' do
752     authorize_with :user_bar_in_sharing_group
753
754     act_as_system_user do
755       Link.create!(
756         tail_uuid: users(:user_bar_in_sharing_group).uuid,
757         link_class: 'permission',
758         name: 'can_read',
759         head_uuid: groups(:project_owned_by_foo).uuid)
760     end
761
762     get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
763
764     assert_equal 1, json_response['items'].length
765     assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
766
767     assert_equal 1, json_response['included'].length
768     assert_equal json_response['included'][0]["uuid"], users(:user_foo_in_sharing_group).uuid
769   end
770
771   test 'get shared, owned by unreadable project' do
772     authorize_with :user_bar_in_sharing_group
773
774     act_as_system_user do
775       Group.find_by_uuid(groups(:project_owned_by_foo).uuid).update!(owner_uuid: groups(:aproject).uuid)
776       Link.create!(
777         tail_uuid: users(:user_bar_in_sharing_group).uuid,
778         link_class: 'permission',
779         name: 'can_read',
780         head_uuid: groups(:project_owned_by_foo).uuid)
781     end
782
783     get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
784
785     assert_equal 1, json_response['items'].length
786     assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
787
788     assert_equal 0, json_response['included'].length
789   end
790
791   test 'get shared, owned by non-project' do
792     authorize_with :user_bar_in_sharing_group
793
794     act_as_system_user do
795       Group.find_by_uuid(groups(:project_owned_by_foo).uuid).update!(owner_uuid: groups(:group_for_sharing_tests).uuid)
796     end
797
798     get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
799
800     assert_equal 1, json_response['items'].length
801     assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
802
803     assert_equal 1, json_response['included'].length
804     assert_equal json_response['included'][0]["uuid"], groups(:group_for_sharing_tests).uuid
805   end
806
807   ### contents with exclude_home_project
808
809   test 'contents, exclude home owned by another user' do
810     authorize_with :user_bar_in_sharing_group
811
812     act_as_system_user do
813       Link.create!(
814         tail_uuid: users(:user_bar_in_sharing_group).uuid,
815         link_class: 'permission',
816         name: 'can_read',
817         head_uuid: groups(:project_owned_by_foo).uuid)
818       Link.create!(
819         tail_uuid: users(:user_bar_in_sharing_group).uuid,
820         link_class: 'permission',
821         name: 'can_read',
822         head_uuid: collections(:collection_owned_by_foo).uuid)
823     end
824
825     get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
826
827     assert_equal 2, json_response['items'].length
828     assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
829     assert_equal json_response['items'][1]["uuid"], collections(:collection_owned_by_foo).uuid
830
831     assert_equal 1, json_response['included'].length
832     assert_equal json_response['included'][0]["uuid"], users(:user_foo_in_sharing_group).uuid
833   end
834
835   test 'contents, exclude home, owned by unreadable project' do
836     authorize_with :user_bar_in_sharing_group
837
838     act_as_system_user do
839       Group.find_by_uuid(groups(:project_owned_by_foo).uuid).update!(owner_uuid: groups(:aproject).uuid)
840       Link.create!(
841         tail_uuid: users(:user_bar_in_sharing_group).uuid,
842         link_class: 'permission',
843         name: 'can_read',
844         head_uuid: groups(:project_owned_by_foo).uuid)
845     end
846
847     get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
848
849     assert_equal 1, json_response['items'].length
850     assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
851
852     assert_equal 0, json_response['included'].length
853   end
854
855   test 'contents, exclude home, owned by non-project' do
856     authorize_with :user_bar_in_sharing_group
857
858     act_as_system_user do
859       Group.find_by_uuid(groups(:project_owned_by_foo).uuid).update!(owner_uuid: groups(:group_for_sharing_tests).uuid)
860     end
861
862     get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
863
864     assert_equal 1, json_response['items'].length
865     assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
866
867     assert_equal 1, json_response['included'].length
868     assert_equal json_response['included'][0]["uuid"], groups(:group_for_sharing_tests).uuid
869   end
870
871   test 'contents, exclude home, with parent specified' do
872     authorize_with :active
873
874     get :contents, params: {id: groups(:aproject).uuid, :include => "owner_uuid", :exclude_home_project => true}
875
876     assert_response 422
877   end
878 end