class Arvados::V1::GroupsControllerTest < ActionController::TestCase
- test "attempt to delete group without read or write access" do
+ test "attempt to delete group that cannot be seen" do
+ Rails.configuration.Users.RoleGroupsVisibleToAll = false
authorize_with :active
- post :destroy, id: groups(:empty_lonely_group).uuid
+ post :destroy, params: {id: groups(:empty_lonely_group).uuid}
assert_response 404
end
+ test "attempt to delete group without read or write access" do
+ authorize_with :active
+ post :destroy, params: {id: groups(:empty_lonely_group).uuid}
+ assert_response 403
+ end
+
test "attempt to delete group without write access" do
authorize_with :active
- post :destroy, id: groups(:all_users).uuid
+ post :destroy, params: {id: groups(:all_users).uuid}
assert_response 403
end
test "get list of projects" do
authorize_with :active
- get :index, filters: [['group_class', '=', 'project']], format: :json
+ get :index, params: {filters: [['group_class', '=', 'project']], format: :json}
assert_response :success
group_uuids = []
json_response['items'].each do |group|
end
assert_includes group_uuids, groups(:aproject).uuid
assert_includes group_uuids, groups(:asubproject).uuid
+ assert_includes group_uuids, groups(:private).uuid
assert_not_includes group_uuids, groups(:system_group).uuid
- assert_not_includes group_uuids, groups(:private).uuid
+ assert_not_includes group_uuids, groups(:private_and_can_read_foofile).uuid
end
test "get list of groups that are not projects" do
authorize_with :active
- get :index, filters: [['group_class', '!=', 'project']], format: :json
+ get :index, params: {filters: [['group_class', '!=', 'project']], format: :json}
assert_response :success
group_uuids = []
json_response['items'].each do |group|
end
assert_not_includes group_uuids, groups(:aproject).uuid
assert_not_includes group_uuids, groups(:asubproject).uuid
- assert_includes group_uuids, groups(:private).uuid
- assert_includes group_uuids, groups(:group_with_no_class).uuid
end
test "get list of groups with bogus group_class" do
authorize_with :active
- get :index, {
+ get :index, params: {
filters: [['group_class', '=', 'nogrouphasthislittleclass']],
format: :json,
}
test 'get group-owned objects' do
authorize_with :active
- get :contents, {
+ get :contents, params: {
id: groups(:aproject).uuid,
format: :json,
}
test "user with project read permission can see project objects" do
authorize_with :project_viewer
- get :contents, {
+ get :contents, params: {
id: groups(:aproject).uuid,
format: :json,
}
test "list objects across projects" do
authorize_with :project_viewer
- get :contents, {
+ get :contents, params: {
format: :json,
filters: [['uuid', 'is_a', 'arvados#specimen']]
}
test "list trashed collections and projects" do
authorize_with :active
- get(:contents, {
+ get(:contents, params: {
format: :json,
include_trash: true,
filters: [
test "list objects in home project" do
authorize_with :active
- get :contents, {
+ get :contents, params: {
format: :json,
limit: 200,
id: users(:active).uuid
refute_includes found_uuids, specimens(:in_asubproject).uuid, "specimen appeared unexpectedly in home project"
end
+ test "list collections in home project" do
+ authorize_with :active
+ get(:contents, params: {
+ format: :json,
+ filters: [
+ ['uuid', 'is_a', 'arvados#collection'],
+ ],
+ limit: 200,
+ id: users(:active).uuid,
+ })
+ assert_response :success
+ found_uuids = json_response['items'].collect { |i| i['uuid'] }
+ assert_includes found_uuids, collections(:collection_owned_by_active).uuid, "collection did not appear in home project"
+ refute_includes found_uuids, collections(:collection_owned_by_active_past_version_1).uuid, "collection appeared unexpectedly in home project"
+ end
+
+ test "list collections in home project, including old versions" do
+ authorize_with :active
+ get(:contents, params: {
+ format: :json,
+ include_old_versions: true,
+ filters: [
+ ['uuid', 'is_a', 'arvados#collection'],
+ ],
+ limit: 200,
+ id: users(:active).uuid,
+ })
+ assert_response :success
+ found_uuids = json_response['items'].collect { |i| i['uuid'] }
+ assert_includes found_uuids, collections(:collection_owned_by_active).uuid, "collection did not appear in home project"
+ assert_includes found_uuids, collections(:collection_owned_by_active_past_version_1).uuid, "old collection version did not appear in home project"
+ end
+
test "user with project read permission can see project collections" do
authorize_with :project_viewer
- get :contents, {
+ get :contents, params: {
id: groups(:asubproject).uuid,
format: :json,
}
].each do |column, order, operator, field|
test "user with project read permission can sort projects on #{column} #{order}" do
authorize_with :project_viewer
- get :contents, {
+ get :contents, params: {
id: groups(:asubproject).uuid,
format: :json,
filters: [['uuid', 'is_a', "arvados#collection"]],
# project tests.
def check_new_project_link_fails(link_attrs)
@controller = Arvados::V1::LinksController.new
- post :create, link: {
- link_class: "permission",
- name: "can_read",
- head_uuid: groups(:aproject).uuid,
- }.merge(link_attrs)
+ post :create, params: {
+ link: {
+ link_class: "permission",
+ name: "can_read",
+ head_uuid: groups(:aproject).uuid,
+ }.merge(link_attrs)
+ }
assert_includes(403..422, response.status)
end
test "user with project read permission can't rename items in it" do
authorize_with :project_viewer
@controller = Arvados::V1::LinksController.new
- post :update, {
+ post :update, params: {
id: jobs(:running).uuid,
name: "Denied test name",
}
test "user with project read permission can't remove items from it" do
@controller = Arvados::V1::PipelineTemplatesController.new
authorize_with :project_viewer
- post :update, {
+ post :update, params: {
id: pipeline_templates(:two_part).uuid,
pipeline_template: {
owner_uuid: users(:project_viewer).uuid,
test "user with project read permission can't delete it" do
authorize_with :project_viewer
- post :destroy, {id: groups(:aproject).uuid}
+ post :destroy, params: {id: groups(:aproject).uuid}
assert_response 403
end
test 'get group-owned objects with limit' do
authorize_with :active
- get :contents, {
+ get :contents, params: {
id: groups(:aproject).uuid,
limit: 1,
format: :json,
test 'get group-owned objects with limit and offset' do
authorize_with :active
- get :contents, {
+ get :contents, params: {
id: groups(:aproject).uuid,
limit: 1,
offset: 12345,
assert_equal 0, json_response['items'].count
end
+ test 'get group-owned objects with select' do
+ authorize_with :active
+ get :contents, params: {
+ id: groups(:aproject).uuid,
+ limit: 100,
+ format: :json,
+ select: ["uuid", "collections.name"]
+ }
+ assert_response :success
+ assert_equal 17, json_response['items_available']
+ assert_equal 17, json_response['items'].count
+ json_response['items'].each do |item|
+ # Expect collections to have a name field, other items should not.
+ if item["kind"] == "arvados#collection"
+ assert !item["name"].nil?
+ else
+ assert item["name"].nil?
+ end
+ end
+ end
+
test 'get group-owned objects with additional filter matching nothing' do
authorize_with :active
- get :contents, {
+ get :contents, params: {
id: groups(:aproject).uuid,
filters: [['uuid', 'in', ['foo_not_a_uuid','bar_not_a_uuid']]],
format: :json,
['foo', '', '1234five', '0x10', '-8'].each do |val|
test "Raise error on bogus #{arg} parameter #{val.inspect}" do
authorize_with :active
- get :contents, {
+ get :contents, params: {
:id => groups(:aproject).uuid,
:format => :json,
arg => val,
end
end
- test "Collection contents don't include manifest_text" do
+ test "Collection contents don't include manifest_text or unsigned_manifest_text" do
authorize_with :active
- get :contents, {
+ get :contents, params: {
id: groups(:aproject).uuid,
filters: [["uuid", "is_a", "arvados#collection"]],
format: :json,
refute(json_response["items"].any? { |c| not c["portable_data_hash"] },
"response included an item without a portable data hash")
refute(json_response["items"].any? { |c| c.include?("manifest_text") },
- "response included an item with a manifest text")
+ "response included an item with manifest_text")
+ refute(json_response["items"].any? { |c| c.include?("unsigned_manifest_text") },
+ "response included an item with unsigned_manifest_text")
end
test 'get writable_by list for owned group' do
authorize_with :active
- get :show, {
+ get :show, params: {
id: groups(:aproject).uuid,
format: :json
}
test 'no writable_by list for group with read-only access' do
authorize_with :rominiadmin
- get :show, {
+ get :show, params: {
id: groups(:testusergroup_admins).uuid,
format: :json
}
test 'get writable_by list by admin user' do
authorize_with :admin
- get :show, {
+ get :show, params: {
id: groups(:testusergroup_admins).uuid,
format: :json
}
test 'creating subproject with duplicate name fails' do
authorize_with :active
- post :create, {
+ post :create, params: {
group: {
name: 'A Project',
owner_uuid: users(:active).uuid,
test 'creating duplicate named subproject succeeds with ensure_unique_name' do
authorize_with :active
- post :create, {
+ post :create, params: {
group: {
name: 'A Project',
owner_uuid: users(:active).uuid,
new_project['name'])
end
- test "unsharing a project results in hiding it from previously shared user" do
- # remove sharing link for project
- @controller = Arvados::V1::LinksController.new
- authorize_with :admin
- post :destroy, id: links(:share_starred_project_with_project_viewer).uuid
- assert_response :success
-
- # verify that the user can no longer see the project
- @test_counter = 0 # Reset executed action counter
- @controller = Arvados::V1::GroupsController.new
- authorize_with :project_viewer
- get :index, filters: [['group_class', '=', 'project']], format: :json
- assert_response :success
- found_projects = {}
- json_response['items'].each do |g|
- found_projects[g['uuid']] = g
- end
- assert_equal false, found_projects.include?(groups(:starred_and_shared_active_user_project).uuid)
-
- # share the project
- @test_counter = 0
- @controller = Arvados::V1::LinksController.new
- authorize_with :system_user
- post :create, link: {
- link_class: "permission",
- name: "can_read",
- head_uuid: groups(:starred_and_shared_active_user_project).uuid,
- tail_uuid: users(:project_viewer).uuid,
- }
-
- # verify that project_viewer user can now see shared project again
- @test_counter = 0
- @controller = Arvados::V1::GroupsController.new
- authorize_with :project_viewer
- get :index, filters: [['group_class', '=', 'project']], format: :json
- assert_response :success
- found_projects = {}
- json_response['items'].each do |g|
- found_projects[g['uuid']] = g
- end
- assert_equal true, found_projects.include?(groups(:starred_and_shared_active_user_project).uuid)
- end
-
[
[['owner_uuid', '!=', 'zzzzz-tpzed-xurymjxw79nv3jz'], 200,
'zzzzz-d1hrv-subprojpipeline', 'zzzzz-d1hrv-1xfj6xkicf2muk2'],
].each do |filter, expect_code, expect_uuid, not_expect_uuid|
test "get contents with '#{filter}' filter" do
authorize_with :active
- get :contents, filters: [filter], format: :json
+ get :contents, params: {filters: [filter], format: :json}
assert_response expect_code
if expect_code == 200
assert_not_empty json_response['items']
end
test 'get contents with jobs and pipeline instances disabled' do
- Rails.configuration.disable_api_methods = ['jobs.index', 'pipeline_instances.index']
+ Rails.configuration.API.DisabledAPIs = ConfigLoader.to_OrderedOptions(
+ {'jobs.index'=>{}, 'pipeline_instances.index'=>{}})
authorize_with :active
- get :contents, {
+ get :contents, params: {
id: groups(:aproject).uuid,
format: :json,
}
test 'get contents with low max_index_database_read' do
# Some result will certainly have at least 12 bytes in a
# restricted column
- Rails.configuration.max_index_database_read = 12
+ Rails.configuration.API.MaxIndexDatabaseRead = 12
authorize_with :active
- get :contents, {
+ get :contents, params: {
id: groups(:aproject).uuid,
format: :json,
}
recursive: true,
format: :json,
}
- get :contents, params
+ get :contents, params: params
owners = json_response['items'].map do |item|
item['owner_uuid']
end
format: :json,
}
params[:recursive] = false if recursive == false
- get :contents, params
+ get :contents, params: params
owners = json_response['items'].map do |item|
item['owner_uuid']
end
test 'get home project contents, recursive=true' do
authorize_with :active
- get :contents, {
+ get :contents, params: {
id: users(:active).uuid,
recursive: true,
format: :json,
assert_includes(owners, groups(:asubproject).uuid)
end
+ [:afiltergroup, :private_role].each do |grp|
+ test "delete non-project group #{grp}" do
+ authorize_with :admin
+ assert_not_nil Group.find_by_uuid(groups(grp).uuid)
+ assert !Group.find_by_uuid(groups(grp).uuid).is_trashed
+ post :destroy, params: {
+ id: groups(grp).uuid,
+ format: :json,
+ }
+ assert_response :success
+ # Should not be trashed
+ assert_nil Group.find_by_uuid(groups(grp).uuid)
+ end
+ end
+
+ [
+ [false, :inactive, :private_role, false],
+ [false, :spectator, :private_role, false],
+ [false, :admin, :private_role, true],
+ [true, :inactive, :private_role, false],
+ [true, :spectator, :private_role, true],
+ [true, :admin, :private_role, true],
+ # project (non-role) groups are invisible even when RoleGroupsVisibleToAll is true
+ [true, :inactive, :private, false],
+ [true, :spectator, :private, false],
+ [true, :admin, :private, true],
+ ].each do |visibleToAll, userFixture, groupFixture, visible|
+ test "with RoleGroupsVisibleToAll=#{visibleToAll}, #{groupFixture} group is #{visible ? '' : 'in'}visible to #{userFixture} user" do
+ Rails.configuration.Users.RoleGroupsVisibleToAll = visibleToAll
+ authorize_with userFixture
+ get :show, params: {id: groups(groupFixture).uuid, format: :json}
+ if visible
+ assert_response :success
+ else
+ assert_response 404
+ end
+ end
+ end
+
### trashed project tests ###
- [:active, :admin].each do |auth|
+ #
+ # The structure is
+ #
+ # trashed_project (zzzzz-j7d0g-trashedproject1)
+ # trashed_subproject (zzzzz-j7d0g-trashedproject2)
+ # trashed_subproject3 (zzzzz-j7d0g-trashedproject3)
+ # zzzzz-xvhdp-cr5trashedcontr
+
+ [:active,
+ :admin].each do |auth|
# project: to query, to untrash, is visible, parent contents listing success
- [[:trashed_project, [], false, true],
+ [
+ [:trashed_project, [], false, true],
[:trashed_project, [:trashed_project], true, true],
[:trashed_subproject, [], false, false],
[:trashed_subproject, [:trashed_project], true, true],
untrash.each do |pr|
Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
end
- get :contents, {
+ get :contents, params: {
id: groups(project).owner_uuid,
format: :json
}
untrash.each do |pr|
Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
end
- get :contents, {
+ get :contents, params: {
id: groups(project).uuid,
format: :json
}
untrash.each do |pr|
Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
end
- get :index, {
+ get :index, params: {
format: :json,
}
assert_response :success
untrash.each do |pr|
Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
end
- get :show, {
+ get :show, params: {
id: groups(project).uuid,
format: :json
}
end
end
+ test "show include_trash=false #{project} #{untrash} as #{auth}" do
+ authorize_with auth
+ untrash.each do |pr|
+ Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
+ end
+ get :show, params: {
+ id: groups(project).uuid,
+ format: :json,
+ include_trash: false
+ }
+ if visible
+ assert_response :success
+ else
+ assert_response 404
+ end
+ end
+
test "show include_trash #{project} #{untrash} as #{auth}" do
authorize_with auth
untrash.each do |pr|
Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
end
- get :show, {
+ get :show, params: {
id: groups(project).uuid,
format: :json,
include_trash: true
untrash.each do |pr|
Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
end
- get :index, {
+ get :index, params: {
format: :json,
include_trash: true
}
Group.find_by_uuid(groups(pr).uuid).update! is_trashed: false
end
assert !Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
- post :destroy, {
+ post :destroy, params: {
id: groups(:trashed_project).uuid,
format: :json,
}
test "untrash project #{auth}" do
authorize_with auth
assert Group.find_by_uuid(groups(:trashed_project).uuid).is_trashed
- post :untrash, {
+ post :untrash, params: {
id: groups(:trashed_project).uuid,
format: :json,
}
gc = Group.create!({owner_uuid: "zzzzz-j7d0g-trashedproject1",
name: "trashed subproject 3",
group_class: "project"})
- post :untrash, {
+ post :untrash, params: {
id: groups(:trashed_subproject3).uuid,
format: :json,
ensure_unique_name: true
test "move trashed subproject to new owner #{auth}" do
authorize_with auth
assert_nil Group.readable_by(users(auth)).where(uuid: groups(:trashed_subproject).uuid).first
- put :update, {
+ put :update, params: {
id: groups(:trashed_subproject).uuid,
group: {
owner_uuid: users(:active).uuid
end
end
+ # the group class overrides the destroy method. Make sure that the destroyed
+ # object is returned
+ [
+ {group_class: "project"},
+ {group_class: "role"},
+ {group_class: "filter", properties: {"filters":[]}},
+ ].each do |params|
+ test "destroy group #{params} returns object" do
+ authorize_with :active
+
+ group = Group.create!(params)
+
+ post :destroy, params: {
+ id: group.uuid,
+ format: :json,
+ }
+ assert_response :success
+ assert_not_nil json_response
+ assert_equal group.uuid, json_response["uuid"]
+ end
+ end
+
test 'get shared owned by another user' do
authorize_with :user_bar_in_sharing_group
head_uuid: groups(:project_owned_by_foo).uuid)
end
- get :shared, {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
+ get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
assert_equal 1, json_response['items'].length
assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
head_uuid: groups(:project_owned_by_foo).uuid)
end
- get :shared, {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
+ get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
assert_equal 1, json_response['items'].length
assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
assert_equal 0, json_response['included'].length
end
- test 'get shared, owned by non-project' do
+ test 'get shared, add permission link' do
+ authorize_with :user_bar_in_sharing_group
+
+ act_as_system_user do
+ Link.create!(tail_uuid: groups(:group_for_sharing_tests).uuid,
+ head_uuid: groups(:project_owned_by_foo).uuid,
+ link_class: 'permission',
+ name: 'can_manage')
+ end
+
+ get :shared, params: {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
+
+ assert_equal 1, json_response['items'].length
+ assert_equal groups(:project_owned_by_foo).uuid, json_response['items'][0]["uuid"]
+
+ assert_equal 1, json_response['included'].length
+ assert_equal users(:user_foo_in_sharing_group).uuid, json_response['included'][0]["uuid"]
+ end
+
+ ### contents with exclude_home_project
+
+ test 'contents, exclude home owned by another user' do
+ authorize_with :user_bar_in_sharing_group
+
+ act_as_system_user do
+ Link.create!(
+ tail_uuid: users(:user_bar_in_sharing_group).uuid,
+ link_class: 'permission',
+ name: 'can_read',
+ head_uuid: groups(:project_owned_by_foo).uuid)
+ Link.create!(
+ tail_uuid: users(:user_bar_in_sharing_group).uuid,
+ link_class: 'permission',
+ name: 'can_read',
+ head_uuid: collections(:collection_owned_by_foo).uuid)
+ end
+
+ get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
+
+ assert_equal 2, json_response['items'].length
+ assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
+ assert_equal json_response['items'][1]["uuid"], collections(:collection_owned_by_foo).uuid
+
+ assert_equal 1, json_response['included'].length
+ assert_equal json_response['included'][0]["uuid"], users(:user_foo_in_sharing_group).uuid
+ end
+
+ test 'contents, exclude home, owned by unreadable project' do
authorize_with :user_bar_in_sharing_group
act_as_system_user do
- Group.find_by_uuid(groups(:project_owned_by_foo).uuid).update!(owner_uuid: groups(:group_for_sharing_tests).uuid)
+ Group.find_by_uuid(groups(:project_owned_by_foo).uuid).update!(owner_uuid: groups(:aproject).uuid)
+ Link.create!(
+ tail_uuid: users(:user_bar_in_sharing_group).uuid,
+ link_class: 'permission',
+ name: 'can_read',
+ head_uuid: groups(:project_owned_by_foo).uuid)
end
- get :shared, {:filters => [["group_class", "=", "project"]], :include => "owner_uuid"}
+ get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
assert_equal 1, json_response['items'].length
assert_equal json_response['items'][0]["uuid"], groups(:project_owned_by_foo).uuid
+ assert_equal 0, json_response['included'].length
+ end
+
+ test 'contents, exclude home, add permission link' do
+ authorize_with :user_bar_in_sharing_group
+
+ act_as_system_user do
+ Link.create!(tail_uuid: groups(:group_for_sharing_tests).uuid,
+ head_uuid: groups(:project_owned_by_foo).uuid,
+ link_class: 'permission',
+ name: 'can_manage')
+ end
+
+ get :contents, params: {:include => "owner_uuid", :exclude_home_project => true}
+
+ assert_equal 1, json_response['items'].length
+ assert_equal groups(:project_owned_by_foo).uuid, json_response['items'][0]["uuid"]
+
assert_equal 1, json_response['included'].length
- assert_equal json_response['included'][0]["uuid"], groups(:group_for_sharing_tests).uuid
+ assert_equal users(:user_foo_in_sharing_group).uuid, json_response['included'][0]["uuid"]
end
+ test 'contents, exclude home, with parent specified' do
+ authorize_with :active
+
+ get :contents, params: {id: groups(:aproject).uuid, :include => "owner_uuid", :exclude_home_project => true}
+
+ assert_response 422
+ end
+
+ test "include_trash does not return trash inside frozen project" do
+ authorize_with :active
+ trashtime = Time.now - 1.second
+ outerproj = Group.create!(group_class: 'project')
+ innerproj = Group.create!(group_class: 'project', owner_uuid: outerproj.uuid)
+ innercoll = Collection.create!(name: 'inner-not-trashed', owner_uuid: innerproj.uuid)
+ innertrash = Collection.create!(name: 'inner-trashed', owner_uuid: innerproj.uuid, trash_at: trashtime)
+ innertrashproj = Group.create!(group_class: 'project', name: 'inner-trashed-proj', owner_uuid: innerproj.uuid, trash_at: trashtime)
+ outertrash = Collection.create!(name: 'outer-trashed', owner_uuid: outerproj.uuid, trash_at: trashtime)
+ innerproj.update_attributes!(frozen_by_uuid: users(:active).uuid)
+ get :contents, params: {id: outerproj.uuid, include_trash: true, recursive: true}
+ assert_response :success
+ uuids = json_response['items'].collect { |item| item['uuid'] }
+ assert_includes uuids, outertrash.uuid
+ assert_includes uuids, innerproj.uuid
+ assert_includes uuids, innercoll.uuid
+ refute_includes uuids, innertrash.uuid
+ refute_includes uuids, innertrashproj.uuid
+ end
end