Merge branch '8784-dir-listings'
[arvados.git] / services / api / test / functional / arvados / v1 / collections_controller_test.rb
index eeeedcee0183d2d7a2d0767c5c2ea5143d7e3fe2..56b0790a0a5e3920968e6ff580f5909f301941bc 100644 (file)
@@ -1,8 +1,14 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 require 'test_helper'
 
 class Arvados::V1::CollectionsControllerTest < ActionController::TestCase
   include DbCurrentTime
 
+  PERM_TOKEN_RE = /\+A[[:xdigit:]]+@[[:xdigit:]]{8}\b/
+
   def permit_unsigned_manifests isok=true
     # Set security model for the life of a test.
     Rails.configuration.permit_create_collection_with_unsigned_manifest = isok
@@ -11,11 +17,23 @@ class Arvados::V1::CollectionsControllerTest < ActionController::TestCase
   def assert_signed_manifest manifest_text, label=''
     assert_not_nil manifest_text, "#{label} manifest_text was nil"
     manifest_text.scan(/ [[:xdigit:]]{32}\S*/) do |tok|
-      assert_match(/\+A[[:xdigit:]]+@[[:xdigit:]]{8}\b/, tok,
+      assert_match(PERM_TOKEN_RE, tok,
                    "Locator in #{label} manifest_text was not signed")
     end
   end
 
+  def assert_unsigned_manifest resp, label=''
+    txt = resp['unsigned_manifest_text']
+    assert_not_nil(txt, "#{label} unsigned_manifest_text was nil")
+    locs = 0
+    txt.scan(/ [[:xdigit:]]{32}\S*/) do |tok|
+      locs += 1
+      refute_match(PERM_TOKEN_RE, tok,
+                   "Locator in #{label} unsigned_manifest_text was signed: #{tok}")
+    end
+    return locs
+  end
+
   test "should get index" do
     authorize_with :active
     get :index
@@ -25,12 +43,13 @@ class Arvados::V1::CollectionsControllerTest < ActionController::TestCase
            "basic Collections index included manifest_text")
   end
 
-  test "collections.get returns signed locators" do
+  test "collections.get returns signed locators, and no unsigned_manifest_text" do
     permit_unsigned_manifests
     authorize_with :active
     get :show, {id: collections(:foo_file).uuid}
     assert_response :success
     assert_signed_manifest json_response['manifest_text'], 'foo_file'
+    refute_includes json_response, 'unsigned_manifest_text'
   end
 
   test "index with manifest_text selected returns signed locators" do
@@ -41,12 +60,26 @@ class Arvados::V1::CollectionsControllerTest < ActionController::TestCase
     assert(assigns(:objects).andand.any?,
            "no Collections returned for index with columns selected")
     json_response["items"].each do |coll|
-      assert_equal(columns, columns & coll.keys,
+      assert_equal(coll.keys - ['kind'], columns,
                    "Collections index did not respect selected columns")
       assert_signed_manifest coll['manifest_text'], coll['uuid']
     end
   end
 
+  test "index with unsigned_manifest_text selected returns only unsigned locators" do
+    authorize_with :active
+    get :index, select: ['unsigned_manifest_text']
+    assert_response :success
+    assert_operator json_response["items"].count, :>, 0
+    locs = 0
+    json_response["items"].each do |coll|
+      assert_equal(coll.keys - ['kind'], ['unsigned_manifest_text'],
+                   "Collections index did not respect selected columns")
+      locs += assert_unsigned_manifest coll, coll['uuid']
+    end
+    assert_operator locs, :>, 0, "no locators found in any manifests"
+  end
+
   test 'index without select returns everything except manifest' do
     authorize_with :active
     get :index
@@ -254,12 +287,12 @@ EOS
       assert_response :success
       assert_not_nil assigns(:object)
       resp = assigns(:object)
-      assert_equal foo_collection[:portable_data_hash], resp['portable_data_hash']
-      assert_signed_manifest resp['manifest_text']
+      assert_equal foo_collection[:portable_data_hash], resp[:portable_data_hash]
+      assert_signed_manifest resp[:manifest_text]
 
       # The manifest in the response will have had permission hints added.
       # Remove any permission hints in the response before comparing it to the source.
-      stripped_manifest = resp['manifest_text'].gsub(/\+A[A-Za-z0-9@_-]+/, '')
+      stripped_manifest = resp[:manifest_text].gsub(/\+A[A-Za-z0-9@_-]+/, '')
       assert_equal foo_collection[:manifest_text], stripped_manifest
     end
   end
@@ -316,7 +349,7 @@ EOS
         ensure_unique_name: true
       }
       assert_response :success
-      assert_equal 'owned_by_active (2)', json_response['name']
+      assert_match /^owned_by_active \(\d{4}-\d\d-\d\d.*?Z\)$/, json_response['name']
     end
   end
 
@@ -995,4 +1028,66 @@ EOS
       assert_operator c.delete_at, :>=, time_before_trashing + Rails.configuration.default_trash_lifetime
     end
   end
+
+  test 'untrash a trashed collection' do
+    authorize_with :active
+    post :untrash, {
+      id: collections(:expired_collection).uuid,
+    }
+    assert_response 200
+    assert_equal false, json_response['is_trashed']
+    assert_nil json_response['trash_at']
+  end
+
+  test 'untrash error on not trashed collection' do
+    authorize_with :active
+    post :untrash, {
+      id: collections(:collection_owned_by_active).uuid,
+    }
+    assert_response 422
+  end
+
+  [:active, :admin].each do |user|
+    test "get trashed collections as #{user}" do
+      authorize_with user
+      get :index, {
+        filters: [["is_trashed", "=", true]],
+        include_trash: true,
+      }
+      assert_response :success
+
+      items = []
+      json_response["items"].each do |coll|
+        items << coll['uuid']
+      end
+
+      assert_includes(items, collections('unique_expired_collection')['uuid'])
+      if user == :admin
+        assert_includes(items, collections('unique_expired_collection2')['uuid'])
+      else
+        assert_not_includes(items, collections('unique_expired_collection2')['uuid'])
+      end
+    end
+  end
+
+  test 'untrash collection with same name as another with no ensure unique name' do
+    authorize_with :active
+    post :untrash, {
+      id: collections(:trashed_collection_to_test_name_conflict_on_untrash).uuid,
+    }
+    assert_response 422
+  end
+
+  test 'untrash collection with same name as another with ensure unique name' do
+    authorize_with :active
+    post :untrash, {
+      id: collections(:trashed_collection_to_test_name_conflict_on_untrash).uuid,
+      ensure_unique_name: true
+    }
+    assert_response 200
+    assert_equal false, json_response['is_trashed']
+    assert_nil json_response['trash_at']
+    assert_nil json_response['delete_at']
+    assert_match /^same name for trashed and persisted collections \(\d{4}-\d\d-\d\d.*?Z\)$/, json_response['name']
+  end
 end