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_includes group_uuids, groups(:private).uuid
33 assert_not_includes group_uuids, groups(:system_group).uuid
34 assert_not_includes group_uuids, groups(:private_and_can_read_foofile).uuid
37 test "get list of groups that are not projects" do
38 authorize_with :active
39 get :index, params: {filters: [['group_class', '!=', 'project']], format: :json}
40 assert_response :success
42 json_response['items'].each do |group|
43 assert_not_equal 'project', group['group_class']
44 group_uuids << group['uuid']
46 assert_not_includes group_uuids, groups(:aproject).uuid
47 assert_not_includes group_uuids, groups(:asubproject).uuid
50 test "get list of groups with bogus group_class" do
51 authorize_with :active
53 filters: [['group_class', '=', 'nogrouphasthislittleclass']],
56 assert_response :success
57 assert_equal [], json_response['items']
58 assert_equal 0, json_response['items_available']
61 def check_project_contents_response disabled_kinds=[]
62 assert_response :success
63 assert_operator 2, :<=, json_response['items_available']
64 assert_operator 2, :<=, json_response['items'].count
65 kinds = json_response['items'].collect { |i| i['kind'] }.uniq
66 expect_kinds = %w'arvados#group arvados#specimen arvados#pipelineTemplate arvados#job' - disabled_kinds
67 assert_equal expect_kinds, (expect_kinds & kinds)
69 json_response['items'].each do |i|
70 if i['kind'] == 'arvados#group'
71 assert(i['group_class'] == 'project',
72 "group#contents returned a non-project group")
76 disabled_kinds.each do |d|
77 assert_equal true, !kinds.include?(d)
81 test 'get group-owned objects' do
82 authorize_with :active
83 get :contents, params: {
84 id: groups(:aproject).uuid,
87 check_project_contents_response
90 test "user with project read permission can see project objects" do
91 authorize_with :project_viewer
92 get :contents, params: {
93 id: groups(:aproject).uuid,
96 check_project_contents_response
99 test "list objects across projects" do
100 authorize_with :project_viewer
101 get :contents, params: {
103 filters: [['uuid', 'is_a', 'arvados#specimen']]
105 assert_response :success
106 found_uuids = json_response['items'].collect { |i| i['uuid'] }
107 [[:in_aproject, true],
108 [:in_asubproject, true],
109 [:owned_by_private_group, false]].each do |specimen_fixture, should_find|
111 assert_includes found_uuids, specimens(specimen_fixture).uuid, "did not find specimen fixture '#{specimen_fixture}'"
113 refute_includes found_uuids, specimens(specimen_fixture).uuid, "found specimen fixture '#{specimen_fixture}'"
118 test "list trashed collections and projects" do
119 authorize_with :active
120 get(:contents, params: {
124 ['uuid', 'is_a', ['arvados#collection', 'arvados#group']],
125 ['is_trashed', '=', true],
129 assert_response :success
130 found_uuids = json_response['items'].collect { |i| i['uuid'] }
131 assert_includes found_uuids, groups(:trashed_project).uuid
132 refute_includes found_uuids, groups(:aproject).uuid
133 assert_includes found_uuids, collections(:expired_collection).uuid
134 refute_includes found_uuids, collections(:w_a_z_file).uuid
137 test "list objects in home project" do
138 authorize_with :active
139 get :contents, params: {
142 id: users(:active).uuid
144 assert_response :success
145 found_uuids = json_response['items'].collect { |i| i['uuid'] }
146 assert_includes found_uuids, specimens(:owned_by_active_user).uuid, "specimen did not appear in home project"
147 refute_includes found_uuids, specimens(:in_asubproject).uuid, "specimen appeared unexpectedly in home project"
150 test "list collections in home project" do
151 authorize_with :active
152 get(:contents, params: {
155 ['uuid', 'is_a', 'arvados#collection'],
158 id: users(:active).uuid,
160 assert_response :success
161 found_uuids = json_response['items'].collect { |i| i['uuid'] }
162 assert_includes found_uuids, collections(:collection_owned_by_active).uuid, "collection did not appear in home project"
163 refute_includes found_uuids, collections(:collection_owned_by_active_past_version_1).uuid, "collection appeared unexpectedly in home project"
166 test "list collections in home project, including old versions" do
167 authorize_with :active
168 get(:contents, params: {
170 include_old_versions: true,
172 ['uuid', 'is_a', 'arvados#collection'],
175 id: users(:active).uuid,
177 assert_response :success
178 found_uuids = json_response['items'].collect { |i| i['uuid'] }
179 assert_includes found_uuids, collections(:collection_owned_by_active).uuid, "collection did not appear in home project"
180 assert_includes found_uuids, collections(:collection_owned_by_active_past_version_1).uuid, "old collection version did not appear in home project"
183 test "user with project read permission can see project collections" do
184 authorize_with :project_viewer
185 get :contents, params: {
186 id: groups(:asubproject).uuid,
189 ids = json_response['items'].map { |item| item["uuid"] }
190 assert_includes ids, collections(:baz_file_in_asubproject).uuid
194 ['collections.name', 'asc', :<=, "name"],
195 ['collections.name', 'desc', :>=, "name"],
196 ['name', 'asc', :<=, "name"],
197 ['name', 'desc', :>=, "name"],
198 ['collections.created_at', 'asc', :<=, "created_at"],
199 ['collections.created_at', 'desc', :>=, "created_at"],
200 ['created_at', 'asc', :<=, "created_at"],
201 ['created_at', 'desc', :>=, "created_at"],
202 ].each do |column, order, operator, field|
203 test "user with project read permission can sort projects on #{column} #{order}" do
204 authorize_with :project_viewer
205 get :contents, params: {
206 id: groups(:asubproject).uuid,
208 filters: [['uuid', 'is_a', "arvados#collection"]],
209 order: "#{column} #{order}"
211 sorted_values = json_response['items'].collect { |item| item[field] }
213 # Here we avoid assuming too much about the database
214 # collation. Both "alice"<"Bob" and "alice">"Bob" can be
215 # correct. Hopefully it _is_ safe to assume that if "a" comes
216 # before "b" in the ascii alphabet, "aX">"bY" is never true for
217 # any strings X and Y.
218 reliably_sortable_names = sorted_values.select do |name|
219 name[0] >= 'a' && name[0] <= 'z'
223 # Preserve order of sorted_values. But do not use &=. If
224 # sorted_values has out-of-order duplicates, we want to preserve
225 # them here, so we can detect them and fail the test below.
226 sorted_values.select! do |name|
227 reliably_sortable_names.include? name
230 assert_sorted(operator, sorted_values)
234 def assert_sorted(operator, sorted_items)
235 actually_checked_anything = false
237 sorted_items.each do |entry|
239 assert_operator(previous, operator, entry,
240 "Entries sorted incorrectly.")
241 actually_checked_anything = true
245 assert actually_checked_anything, "Didn't even find two items to compare."
248 # Even though the project_viewer tests go through other controllers,
249 # I'm putting them here so they're easy to find alongside the other
251 def check_new_project_link_fails(link_attrs)
252 @controller = Arvados::V1::LinksController.new
253 post :create, params: {
255 link_class: "permission",
257 head_uuid: groups(:aproject).uuid,
260 assert_includes(403..422, response.status)
263 test "user with project read permission can't add users to it" do
264 authorize_with :project_viewer
265 check_new_project_link_fails(tail_uuid: users(:spectator).uuid)
268 test "user with project read permission can't add items to it" do
269 authorize_with :project_viewer
270 check_new_project_link_fails(tail_uuid: collections(:baz_file).uuid)
273 test "user with project read permission can't rename items in it" do
274 authorize_with :project_viewer
275 @controller = Arvados::V1::LinksController.new
276 post :update, params: {
277 id: jobs(:running).uuid,
278 name: "Denied test name",
280 assert_includes(403..404, response.status)
283 test "user with project read permission can't remove items from it" do
284 @controller = Arvados::V1::PipelineTemplatesController.new
285 authorize_with :project_viewer
286 post :update, params: {
287 id: pipeline_templates(:two_part).uuid,
289 owner_uuid: users(:project_viewer).uuid,
295 test "user with project read permission can't delete it" do
296 authorize_with :project_viewer
297 post :destroy, params: {id: groups(:aproject).uuid}
301 test 'get group-owned objects with limit' do
302 authorize_with :active
303 get :contents, params: {
304 id: groups(:aproject).uuid,
308 assert_response :success
309 assert_operator 1, :<, json_response['items_available']
310 assert_equal 1, json_response['items'].count
313 test 'get group-owned objects with limit and offset' do
314 authorize_with :active
315 get :contents, params: {
316 id: groups(:aproject).uuid,
321 assert_response :success
322 assert_operator 1, :<, json_response['items_available']
323 assert_equal 0, json_response['items'].count
326 test 'get group-owned objects with additional filter matching nothing' do
327 authorize_with :active
328 get :contents, params: {
329 id: groups(:aproject).uuid,
330 filters: [['uuid', 'in', ['foo_not_a_uuid','bar_not_a_uuid']]],
333 assert_response :success
334 assert_equal [], json_response['items']
335 assert_equal 0, json_response['items_available']
338 %w(offset limit).each do |arg|
339 ['foo', '', '1234five', '0x10', '-8'].each do |val|
340 test "Raise error on bogus #{arg} parameter #{val.inspect}" do
341 authorize_with :active
342 get :contents, params: {
343 :id => groups(:aproject).uuid,
352 test "Collection contents don't include manifest_text or unsigned_manifest_text" do
353 authorize_with :active
354 get :contents, params: {
355 id: groups(:aproject).uuid,
356 filters: [["uuid", "is_a", "arvados#collection"]],
359 assert_response :success
360 refute(json_response["items"].any? { |c| not c["portable_data_hash"] },
361 "response included an item without a portable data hash")
362 refute(json_response["items"].any? { |c| c.include?("manifest_text") },
363 "response included an item with manifest_text")
364 refute(json_response["items"].any? { |c| c.include?("unsigned_manifest_text") },
365 "response included an item with unsigned_manifest_text")
368 test 'get writable_by list for owned group' do
369 authorize_with :active
371 id: groups(:aproject).uuid,
374 assert_response :success
375 assert_not_nil(json_response['writable_by'],
376 "Should receive uuid list in 'writable_by' field")
377 assert_includes(json_response['writable_by'], users(:active).uuid,
378 "owner should be included in writable_by list")
381 test 'no writable_by list for group with read-only access' do
382 authorize_with :rominiadmin
384 id: groups(:testusergroup_admins).uuid,
387 assert_response :success
388 assert_equal([json_response['owner_uuid']],
389 json_response['writable_by'],
390 "Should only see owner_uuid in 'writable_by' field")
393 test 'get writable_by list by admin user' do
394 authorize_with :admin
396 id: groups(:testusergroup_admins).uuid,
399 assert_response :success
400 assert_not_nil(json_response['writable_by'],
401 "Should receive uuid list in 'writable_by' field")
402 assert_includes(json_response['writable_by'],
404 "Current user should be included in 'writable_by' field")
407 test 'creating subproject with duplicate name fails' do
408 authorize_with :active
409 post :create, params: {
412 owner_uuid: users(:active).uuid,
413 group_class: 'project',
417 response_errors = json_response['errors']
418 assert_not_nil response_errors, 'Expected error in response'
419 assert(response_errors.first.include?('duplicate key'),
420 "Expected 'duplicate key' error in #{response_errors.first}")
423 test 'creating duplicate named subproject succeeds with ensure_unique_name' do
424 authorize_with :active
425 post :create, params: {
428 owner_uuid: users(:active).uuid,
429 group_class: 'project',
431 ensure_unique_name: true
433 assert_response :success
434 new_project = json_response
435 assert_not_equal(new_project['uuid'],
436 groups(:aproject).uuid,
437 "create returned same uuid as existing project")
438 assert_match(/^A Project \(\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z\)$/,
443 [['owner_uuid', '!=', 'zzzzz-tpzed-xurymjxw79nv3jz'], 200,
444 'zzzzz-d1hrv-subprojpipeline', 'zzzzz-d1hrv-1xfj6xkicf2muk2'],
445 [["pipeline_instances.state", "not in", ["Complete", "Failed"]], 200,
446 'zzzzz-d1hrv-1xfj6xkicf2muk2', 'zzzzz-d1hrv-i3e77t9z5y8j9cc'],
447 [['container_requests.requesting_container_uuid', '=', nil], 200,
448 'zzzzz-xvhdp-cr4queuedcontnr', 'zzzzz-xvhdp-cr4requestercn2'],
449 [['container_requests.no_such_column', '=', nil], 422],
450 [['container_requests.', '=', nil], 422],
451 [['.requesting_container_uuid', '=', nil], 422],
452 [['no_such_table.uuid', '!=', 'zzzzz-tpzed-xurymjxw79nv3jz'], 422],
453 ].each do |filter, expect_code, expect_uuid, not_expect_uuid|
454 test "get contents with '#{filter}' filter" do
455 authorize_with :active
456 get :contents, params: {filters: [filter], format: :json}
457 assert_response expect_code
458 if expect_code == 200
459 assert_not_empty json_response['items']
460 item_uuids = json_response['items'].collect {|item| item['uuid']}
461 assert_includes(item_uuids, expect_uuid)
462 assert_not_includes(item_uuids, not_expect_uuid)
467 test 'get contents with jobs and pipeline instances disabled' do
468 Rails.configuration.API.DisabledAPIs = ConfigLoader.to_OrderedOptions(
469 {'jobs.index'=>{}, 'pipeline_instances.index'=>{}})
471 authorize_with :active
472 get :contents, params: {
473 id: groups(:aproject).uuid,
476 check_project_contents_response %w'arvados#pipelineInstance arvados#job'
479 test 'get contents with low max_index_database_read' do
480 # Some result will certainly have at least 12 bytes in a
482 Rails.configuration.API.MaxIndexDatabaseRead = 12
483 authorize_with :active
484 get :contents, params: {
485 id: groups(:aproject).uuid,
488 assert_response :success
489 assert_not_empty(json_response['items'])
490 assert_operator(json_response['items'].count,
491 :<, json_response['items_available'])
494 test 'get contents, recursive=true' do
495 authorize_with :active
497 id: groups(:aproject).uuid,
501 get :contents, params: params
502 owners = json_response['items'].map do |item|
505 assert_includes(owners, groups(:aproject).uuid)
506 assert_includes(owners, groups(:asubproject).uuid)
509 [false, nil].each do |recursive|
510 test "get contents, recursive=#{recursive.inspect}" do
511 authorize_with :active
513 id: groups(:aproject).uuid,
516 params[:recursive] = false if recursive == false
517 get :contents, params: params
518 owners = json_response['items'].map do |item|
521 assert_includes(owners, groups(:aproject).uuid)
522 refute_includes(owners, groups(:asubproject).uuid)
526 test 'get home project contents, recursive=true' do
527 authorize_with :active
528 get :contents, params: {
529 id: users(:active).uuid,
533 owners = json_response['items'].map do |item|
536 assert_includes(owners, users(:active).uuid)
537 assert_includes(owners, groups(:aproject).uuid)
538 assert_includes(owners, groups(:asubproject).uuid)
541 [:afiltergroup, :private_role].each do |grp|
542 test "delete non-project group #{grp}" do
543 authorize_with :admin
544 assert_not_nil Group.find_by_uuid(groups(grp).uuid)
545 assert !Group.find_by_uuid(groups(grp).uuid).is_trashed
546 post :destroy, params: {
547 id: groups(grp).uuid,
550 assert_response :success
551 # Should not be trashed
552 assert_nil Group.find_by_uuid(groups(grp).uuid)
556 ### trashed project tests ###
561 # trashed_project (zzzzz-j7d0g-trashedproject1)
562 # trashed_subproject (zzzzz-j7d0g-trashedproject2)
563 # trashed_subproject3 (zzzzz-j7d0g-trashedproject3)
564 # zzzzz-xvhdp-cr5trashedcontr
567 :admin].each do |auth|
568 # project: to query, to untrash, is visible, parent contents listing success
570 [:trashed_project, [], false, true],
571 [:trashed_project, [:trashed_project], true, true],
572 [:trashed_subproject, [], false, false],
573 [:trashed_subproject, [:trashed_project], true, true],
574 [:trashed_subproject3, [:trashed_project], false, true],
575 [:trashed_subproject3, [:trashed_subproject3], false, false],
576 [:trashed_subproject3, [:trashed_project, :trashed_subproject3], true, true],
577 ].each do |project, untrash, visible, success|
579 test "contents listing #{project} #{untrash} as #{auth}" do
582 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
584 get :contents, params: {
585 id: groups(project).owner_uuid,
589 assert_response :success
590 item_uuids = json_response['items'].map do |item|
594 assert_includes(item_uuids, groups(project).uuid)
596 assert_not_includes(item_uuids, groups(project).uuid)
603 test "contents of #{project} #{untrash} as #{auth}" do
606 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
608 get :contents, params: {
609 id: groups(project).uuid,
613 assert_response :success
619 test "index #{project} #{untrash} as #{auth}" do
622 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
624 get :index, params: {
627 assert_response :success
628 item_uuids = json_response['items'].map do |item|
632 assert_includes(item_uuids, groups(project).uuid)
634 assert_not_includes(item_uuids, groups(project).uuid)
638 test "show #{project} #{untrash} as #{auth}" do
641 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
644 id: groups(project).uuid,
648 assert_response :success
654 test "show include_trash=false #{project} #{untrash} as #{auth}" do
657 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
660 id: groups(project).uuid,
665 assert_response :success
671 test "show include_trash #{project} #{untrash} as #{auth}" do
674 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
677 id: groups(project).uuid,
681 assert_response :success
684 test "index include_trash #{project} #{untrash} as #{auth}" do
687 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
689 get :index, params: {
693 assert_response :success
694 item_uuids = json_response['items'].map do |item|
697 assert_includes(item_uuids, groups(project).uuid)
701 test "delete project #{auth}" do
703 [:trashed_project].each do |pr|
704 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
706 assert !Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
707 post :destroy, params: {
708 id: groups(:trashed_project).uuid,
711 assert_response :success
712 assert Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
715 test "untrash project #{auth}" do
717 assert Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
718 post :untrash, params: {
719 id: groups(:trashed_project).uuid,
722 assert_response :success
723 assert !Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
726 test "untrash project with name conflict #{auth}" do
728 [:trashed_project].each do |pr|
729 Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
731 gc = Group.create!({owner_uuid: "zzzzz-j7d0g-trashedproject1",
732 name: "trashed subproject 3",
733 group_class: "project"})
734 post :untrash, params: {
735 id: groups(:trashed_subproject3).uuid,
737 ensure_unique_name: true
739 assert_response :success
740 assert_match /^trashed subproject 3 \(\d{4}-\d\d-\d\d.*?Z\)$/, json_response['name']
743 test "move trashed subproject to new owner #{auth}" do
745 assert_nil Group.readable_by(users(auth)).where(uuid: groups(:trashed_subproject).uuid).first
746 put :update, params: {
747 id: groups(:trashed_subproject).uuid,
749 owner_uuid: users(:active).uuid
754 assert_response :success
755 assert_not_nil Group.readable_by(users(auth)).where(uuid: groups(:trashed_subproject).uuid).first
759 test 'get shared owned by another user' do
760 authorize_with :user_bar_in_sharing_group
762 act_as_system_user do
764 tail_uuid: users(:user_bar_in_sharing_group).uuid,
765 link_class: 'permission',
767 head_uuid: groups(:project_owned_by_foo).uuid)
770 get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
772 assert_equal 1, json_response['items'].length
773 assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
775 assert_equal 1, json_response['included'].length
776 assert_equal json_response['included'][0]["uuid"], users(:user_foo_in_sharing_group).uuid
779 test 'get shared, owned by unreadable project' do
780 authorize_with :user_bar_in_sharing_group
782 act_as_system_user do
783 Group.find_by_uuid(groups(:project_owned_by_foo).uuid).update!(owner_uuid: groups(:aproject).uuid)
785 tail_uuid: users(:user_bar_in_sharing_group).uuid,
786 link_class: 'permission',
788 head_uuid: groups(:project_owned_by_foo).uuid)
791 get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
793 assert_equal 1, json_response['items'].length
794 assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
796 assert_equal 0, json_response['included'].length
799 test 'get shared, add permission link' do
800 authorize_with :user_bar_in_sharing_group
802 act_as_system_user do
803 Link.create!(tail_uuid: groups(:group_for_sharing_tests).uuid,
804 head_uuid: groups(:project_owned_by_foo).uuid,
805 link_class: 'permission',
809 get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
811 assert_equal 1, json_response['items'].length
812 assert_equal groups(:project_owned_by_foo).uuid, json_response['items'][0]["uuid"]
814 assert_equal 1, json_response['included'].length
815 assert_equal users(:user_foo_in_sharing_group).uuid, json_response['included'][0]["uuid"]
818 ### contents with exclude_home_project
820 test 'contents, exclude home owned by another user' do
821 authorize_with :user_bar_in_sharing_group
823 act_as_system_user do
825 tail_uuid: users(:user_bar_in_sharing_group).uuid,
826 link_class: 'permission',
828 head_uuid: groups(:project_owned_by_foo).uuid)
830 tail_uuid: users(:user_bar_in_sharing_group).uuid,
831 link_class: 'permission',
833 head_uuid: collections(:collection_owned_by_foo).uuid)
836 get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
838 assert_equal 2, json_response['items'].length
839 assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
840 assert_equal json_response['items'][1]["uuid"], collections(:collection_owned_by_foo).uuid
842 assert_equal 1, json_response['included'].length
843 assert_equal json_response['included'][0]["uuid"], users(:user_foo_in_sharing_group).uuid
846 test 'contents, exclude home, owned by unreadable project' do
847 authorize_with :user_bar_in_sharing_group
849 act_as_system_user do
850 Group.find_by_uuid(groups(:project_owned_by_foo).uuid).update!(owner_uuid: groups(:aproject).uuid)
852 tail_uuid: users(:user_bar_in_sharing_group).uuid,
853 link_class: 'permission',
855 head_uuid: groups(:project_owned_by_foo).uuid)
858 get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
860 assert_equal 1, json_response['items'].length
861 assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
863 assert_equal 0, json_response['included'].length
866 test 'contents, exclude home, add permission link' do
867 authorize_with :user_bar_in_sharing_group
869 act_as_system_user do
870 Link.create!(tail_uuid: groups(:group_for_sharing_tests).uuid,
871 head_uuid: groups(:project_owned_by_foo).uuid,
872 link_class: 'permission',
876 get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
878 assert_equal 1, json_response['items'].length
879 assert_equal groups(:project_owned_by_foo).uuid, json_response['items'][0]["uuid"]
881 assert_equal 1, json_response['included'].length
882 assert_equal users(:user_foo_in_sharing_group).uuid, json_response['included'][0]["uuid"]
885 test 'contents, exclude home, with parent specified' do
886 authorize_with :active
888 get :contents, params: {id: groups(:aproject).uuid, :include => "owner_uuid", :exclude_home_project => true}