1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
7 class Arvados::V1::GroupsControllerTest < ActionController::TestCase
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}
15 test "attempt to delete group without write access" do
16 authorize_with :active
17 post :destroy, params: {id: groups(:all_users).uuid}
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
26 json_response['items'].each do |group|
27 assert_equal 'project', group['group_class']
28 group_uuids << group['uuid']
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
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
41 json_response['items'].each do |group|
42 assert_not_equal 'project', group['group_class']
43 group_uuids << group['uuid']
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
51 test "get list of groups with bogus group_class" do
52 authorize_with :active
54 filters: [['group_class', '=', 'nogrouphasthislittleclass']],
57 assert_response :success
58 assert_equal [], json_response['items']
59 assert_equal 0, json_response['items_available']
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)
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")
77 disabled_kinds.each do |d|
78 assert_equal true, !kinds.include?(d)
82 test 'get group-owned objects' do
83 authorize_with :active
84 get :contents, params: {
85 id: groups(:aproject).uuid,
88 check_project_contents_response
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,
97 check_project_contents_response
100 test "list objects across projects" do
101 authorize_with :project_viewer
102 get :contents, params: {
104 filters: [['uuid', 'is_a', 'arvados#specimen']]
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|
112 assert_includes found_uuids, specimens(specimen_fixture).uuid, "did not find specimen fixture '#{specimen_fixture}'"
114 refute_includes found_uuids, specimens(specimen_fixture).uuid, "found specimen fixture '#{specimen_fixture}'"
119 test "list trashed collections and projects" do
120 authorize_with :active
121 get(:contents, params: {
125 ['uuid', 'is_a', ['arvados#collection', 'arvados#group']],
126 ['is_trashed', '=', true],
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
138 test "list objects in home project" do
139 authorize_with :active
140 get :contents, params: {
143 id: users(:active).uuid
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"
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,
157 ids = json_response['items'].map { |item| item["uuid"] }
158 assert_includes ids, collections(:baz_file_in_asubproject).uuid
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,
176 filters: [['uuid', 'is_a', "arvados#collection"]],
177 order: "#{column} #{order}"
179 sorted_values = json_response['items'].collect { |item| item[field] }
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'
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
198 assert_sorted(operator, sorted_values)
202 def assert_sorted(operator, sorted_items)
203 actually_checked_anything = false
205 sorted_items.each do |entry|
207 assert_operator(previous, operator, entry,
208 "Entries sorted incorrectly.")
209 actually_checked_anything = true
213 assert actually_checked_anything, "Didn't even find two items to compare."
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
219 def check_new_project_link_fails(link_attrs)
220 @controller = Arvados::V1::LinksController.new
221 post :create, params: {
223 link_class: "permission",
225 head_uuid: groups(:aproject).uuid,
228 assert_includes(403..422, response.status)
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)
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)
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",
248 assert_includes(403..404, response.status)
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,
257 owner_uuid: users(:project_viewer).uuid,
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}
269 test 'get group-owned objects with limit' do
270 authorize_with :active
271 get :contents, params: {
272 id: groups(:aproject).uuid,
276 assert_response :success
277 assert_operator 1, :<, json_response['items_available']
278 assert_equal 1, json_response['items'].count
281 test 'get group-owned objects with limit and offset' do
282 authorize_with :active
283 get :contents, params: {
284 id: groups(:aproject).uuid,
289 assert_response :success
290 assert_operator 1, :<, json_response['items_available']
291 assert_equal 0, json_response['items'].count
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']]],
301 assert_response :success
302 assert_equal [], json_response['items']
303 assert_equal 0, json_response['items_available']
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,
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"]],
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")
334 test 'get writable_by list for owned group' do
335 authorize_with :active
337 id: groups(:aproject).uuid,
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")
347 test 'no writable_by list for group with read-only access' do
348 authorize_with :rominiadmin
350 id: groups(:testusergroup_admins).uuid,
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")
359 test 'get writable_by list by admin user' do
360 authorize_with :admin
362 id: groups(:testusergroup_admins).uuid,
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'],
370 "Current user should be included in 'writable_by' field")
373 test 'creating subproject with duplicate name fails' do
374 authorize_with :active
375 post :create, params: {
378 owner_uuid: users(:active).uuid,
379 group_class: 'project',
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}")
389 test 'creating duplicate named subproject succeeds with ensure_unique_name' do
390 authorize_with :active
391 post :create, params: {
394 owner_uuid: users(:active).uuid,
395 group_class: 'project',
397 ensure_unique_name: true
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\)$/,
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: {
414 link_class: "permission",
416 head_uuid: groups(:starred_and_shared_active_user_project).uuid,
417 tail_uuid: users(:project_viewer).uuid,
420 assert_response :success
421 assert_equal 'permission', json_response['link_class']
422 l = Link.find_by_uuid(json_response['uuid'])
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
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
439 json_response['items'].each do |g|
440 found_projects[g['uuid']] = g
442 assert_equal false, found_projects.include?(groups(:starred_and_shared_active_user_project).uuid)
446 @controller = Arvados::V1::LinksController.new
447 authorize_with :system_user
448 post :create, params: {
450 link_class: "permission",
452 head_uuid: groups(:starred_and_shared_active_user_project).uuid,
453 tail_uuid: users(:project_viewer).uuid,
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)
464 # verify that project_viewer user can now see shared project again
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
471 json_response['items'].each do |g|
472 found_projects[g['uuid']] = g
474 assert_equal true, found_projects.include?(groups(:starred_and_shared_active_user_project).uuid)
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)
502 test 'get contents with jobs and pipeline instances disabled' do
503 Rails.configuration.disable_api_methods = ['jobs.index', 'pipeline_instances.index']
505 authorize_with :active
506 get :contents, params: {
507 id: groups(:aproject).uuid,
510 check_project_contents_response %w'arvados#pipelineInstance arvados#job'
513 test 'get contents with low max_index_database_read' do
514 # Some result will certainly have at least 12 bytes in a
516 Rails.configuration.max_index_database_read = 12
517 authorize_with :active
518 get :contents, params: {
519 id: groups(:aproject).uuid,
522 assert_response :success
523 assert_not_empty(json_response['items'])
524 assert_operator(json_response['items'].count,
525 :<, json_response['items_available'])
528 test 'get contents, recursive=true' do
529 authorize_with :active
531 id: groups(:aproject).uuid,
535 get :contents, params: params
536 owners = json_response['items'].map do |item|
539 assert_includes(owners, groups(:aproject).uuid)
540 assert_includes(owners, groups(:asubproject).uuid)
543 [false, nil].each do |recursive|
544 test "get contents, recursive=#{recursive.inspect}" do
545 authorize_with :active
547 id: groups(:aproject).uuid,
550 params[:recursive] = false if recursive == false
551 get :contents, params: params
552 owners = json_response['items'].map do |item|
555 assert_includes(owners, groups(:aproject).uuid)
556 refute_includes(owners, groups(:asubproject).uuid)
560 test 'get home project contents, recursive=true' do
561 authorize_with :active
562 get :contents, params: {
563 id: users(:active).uuid,
567 owners = json_response['items'].map do |item|
570 assert_includes(owners, users(:active).uuid)
571 assert_includes(owners, groups(:aproject).uuid)
572 assert_includes(owners, groups(:asubproject).uuid)
575 ### trashed project tests ###
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|
588 test "contents listing #{project} #{untrash} as #{auth}" do
591 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
593 get :contents, params: {
594 id: groups(project).owner_uuid,
598 assert_response :success
599 item_uuids = json_response['items'].map do |item|
603 assert_includes(item_uuids, groups(project).uuid)
605 assert_not_includes(item_uuids, groups(project).uuid)
612 test "contents of #{project} #{untrash} as #{auth}" do
615 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
617 get :contents, params: {
618 id: groups(project).uuid,
622 assert_response :success
628 test "index #{project} #{untrash} as #{auth}" do
631 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
633 get :index, params: {
636 assert_response :success
637 item_uuids = json_response['items'].map do |item|
641 assert_includes(item_uuids, groups(project).uuid)
643 assert_not_includes(item_uuids, groups(project).uuid)
647 test "show #{project} #{untrash} as #{auth}" do
650 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
653 id: groups(project).uuid,
657 assert_response :success
663 test "show include_trash #{project} #{untrash} as #{auth}" do
666 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
669 id: groups(project).uuid,
673 assert_response :success
676 test "index include_trash #{project} #{untrash} as #{auth}" do
679 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
681 get :index, params: {
685 assert_response :success
686 item_uuids = json_response['items'].map do |item|
689 assert_includes(item_uuids, groups(project).uuid)
693 test "delete project #{auth}" do
695 [:trashed_project].each do |pr|
696 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
698 assert !Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
699 post :destroy, params: {
700 id: groups(:trashed_project).uuid,
703 assert_response :success
704 assert Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
707 test "untrash project #{auth}" do
709 assert Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
710 post :untrash, params: {
711 id: groups(:trashed_project).uuid,
714 assert_response :success
715 assert !Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
718 test "untrash project with name conflict #{auth}" do
720 [:trashed_project].each do |pr|
721 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
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,
729 ensure_unique_name: true
731 assert_response :success
732 assert_match /^trashed subproject 3 \(\d{4}-\d\d-\d\d.*?Z\)$/, json_response['name']
735 test "move trashed subproject to new owner #{auth}" do
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,
741 owner_uuid: users(:active).uuid
746 assert_response :success
747 assert_not_nil Group.readable_by(users(auth)).where(uuid: groups(:trashed_subproject).uuid).first
751 test 'get shared owned by another user' do
752 authorize_with :user_bar_in_sharing_group
754 act_as_system_user do
756 tail_uuid: users(:user_bar_in_sharing_group).uuid,
757 link_class: 'permission',
759 head_uuid: groups(:project_owned_by_foo).uuid)
762 get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
764 assert_equal 1, json_response['items'].length
765 assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
767 assert_equal 1, json_response['included'].length
768 assert_equal json_response['included'][0]["uuid"], users(:user_foo_in_sharing_group).uuid
771 test 'get shared, owned by unreadable project' do
772 authorize_with :user_bar_in_sharing_group
774 act_as_system_user do
775 Group.find_by_uuid(groups(:project_owned_by_foo).uuid).update!(owner_uuid: groups(:aproject).uuid)
777 tail_uuid: users(:user_bar_in_sharing_group).uuid,
778 link_class: 'permission',
780 head_uuid: groups(:project_owned_by_foo).uuid)
783 get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
785 assert_equal 1, json_response['items'].length
786 assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
788 assert_equal 0, json_response['included'].length
791 test 'get shared, owned by non-project' do
792 authorize_with :user_bar_in_sharing_group
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)
798 get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
800 assert_equal 1, json_response['items'].length
801 assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
803 assert_equal 1, json_response['included'].length
804 assert_equal json_response['included'][0]["uuid"], groups(:group_for_sharing_tests).uuid
807 ### contents with exclude_home_project
809 test 'contents, exclude home owned by another user' do
810 authorize_with :user_bar_in_sharing_group
812 act_as_system_user do
814 tail_uuid: users(:user_bar_in_sharing_group).uuid,
815 link_class: 'permission',
817 head_uuid: groups(:project_owned_by_foo).uuid)
819 tail_uuid: users(:user_bar_in_sharing_group).uuid,
820 link_class: 'permission',
822 head_uuid: collections(:collection_owned_by_foo).uuid)
825 get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
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
831 assert_equal 1, json_response['included'].length
832 assert_equal json_response['included'][0]["uuid"], users(:user_foo_in_sharing_group).uuid
835 test 'contents, exclude home, owned by unreadable project' do
836 authorize_with :user_bar_in_sharing_group
838 act_as_system_user do
839 Group.find_by_uuid(groups(:project_owned_by_foo).uuid).update!(owner_uuid: groups(:aproject).uuid)
841 tail_uuid: users(:user_bar_in_sharing_group).uuid,
842 link_class: 'permission',
844 head_uuid: groups(:project_owned_by_foo).uuid)
847 get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
849 assert_equal 1, json_response['items'].length
850 assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
852 assert_equal 0, json_response['included'].length
855 test 'contents, exclude home, owned by non-project' do
856 authorize_with :user_bar_in_sharing_group
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)
862 get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
864 assert_equal 1, json_response['items'].length
865 assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
867 assert_equal 1, json_response['included'].length
868 assert_equal json_response['included'][0]["uuid"], groups(:group_for_sharing_tests).uuid
871 test 'contents, exclude home, with parent specified' do
872 authorize_with :active
874 get :contents, params: {id: groups(:aproject).uuid, :include => "owner_uuid", :exclude_home_project => true}