2809: Merge branch 'master' refs #2809
[arvados.git] / apps / workbench / test / functional / collections_controller_test.rb
1 require 'test_helper'
2
3 class CollectionsControllerTest < ActionController::TestCase
4   def collection_params(collection_name, file_name=nil)
5     uuid = api_fixture('collections')[collection_name.to_s]['uuid']
6     params = {uuid: uuid, id: uuid}
7     params[:file] = file_name if file_name
8     params
9   end
10
11   def expected_contents(params, token)
12     unless token.is_a? String
13       token = params[:api_token] || token[:arvados_api_token]
14     end
15     [token, params[:uuid], params[:file]].join('/')
16   end
17
18   def assert_hash_includes(actual_hash, expected_hash, msg=nil)
19     expected_hash.each do |key, value|
20       assert_equal(value, actual_hash[key], msg)
21     end
22   end
23
24   def assert_no_session
25     assert_hash_includes(session, {arvados_api_token: nil},
26                          "session includes unexpected API token")
27   end
28
29   def assert_session_for_auth(client_auth)
30     api_token =
31       api_fixture('api_client_authorizations')[client_auth.to_s]['api_token']
32     assert_hash_includes(session, {arvados_api_token: api_token},
33                          "session token does not belong to #{client_auth}")
34   end
35
36   # Mock the collection file reader to avoid external calls and return
37   # a predictable string.
38   CollectionsController.class_eval do
39     def file_enumerator(opts)
40       [[opts[:arvados_api_token], opts[:uuid], opts[:file]].join('/')]
41     end
42   end
43
44   test "viewing a collection" do
45     params = collection_params(:foo_file)
46     sess = session_for(:active)
47     get(:show, params, sess)
48     assert_response :success
49     assert_equal([['.', 'foo', 3]], assigns(:object).files)
50   end
51
52   test "viewing a collection with a reader token" do
53     params = collection_params(:foo_file)
54     params[:reader_tokens] =
55       [api_fixture('api_client_authorizations')['active']['api_token']]
56     get(:show, params)
57     assert_response :success
58     assert_equal([['.', 'foo', 3]], assigns(:object).files)
59     assert_no_session
60   end
61
62   test "viewing the index with a reader token" do
63     params = {reader_tokens:
64       [api_fixture('api_client_authorizations')['spectator']['api_token']]
65     }
66     get(:index, params)
67     assert_response :success
68     assert_no_session
69     listed_collections = assigns(:collections).map { |c| c.uuid }
70     assert_includes(listed_collections,
71                     api_fixture('collections')['bar_file']['uuid'],
72                     "spectator reader token didn't list bar file")
73     refute_includes(listed_collections,
74                     api_fixture('collections')['foo_file']['uuid'],
75                     "spectator reader token listed foo file")
76   end
77
78   test "getting a file from Keep" do
79     params = collection_params(:foo_file, 'foo')
80     sess = session_for(:active)
81     get(:show_file, params, sess)
82     assert_response :success
83     assert_equal(expected_contents(params, sess), @response.body,
84                  "failed to get a correct file from Keep")
85   end
86
87   test "can't get a file from Keep without permission" do
88     params = collection_params(:foo_file, 'foo')
89     sess = session_for(:spectator)
90     get(:show_file, params, sess)
91     assert_includes([403, 404], @response.code.to_i)
92   end
93
94   test "trying to get a nonexistent file from Keep returns a 404" do
95     params = collection_params(:foo_file, 'gone')
96     sess = session_for(:admin)
97     get(:show_file, params, sess)
98     assert_response 404
99   end
100
101   test "getting a file from Keep with a good reader token" do
102     params = collection_params(:foo_file, 'foo')
103     read_token = api_fixture('api_client_authorizations')['active']['api_token']
104     params[:reader_tokens] = [read_token]
105     get(:show_file, params)
106     assert_response :success
107     assert_equal(expected_contents(params, read_token), @response.body,
108                  "failed to get a correct file from Keep using a reader token")
109     assert_not_equal(read_token, session[:arvados_api_token],
110                      "using a reader token set the session's API token")
111   end
112
113   test "trying to get from Keep with an unscoped reader token prompts login" do
114     params = collection_params(:foo_file, 'foo')
115     read_token =
116       api_fixture('api_client_authorizations')['active_noscope']['api_token']
117     params[:reader_tokens] = [read_token]
118     get(:show_file, params)
119     assert_response :redirect
120   end
121
122   test "can get a file with an unpermissioned auth but in-scope reader token" do
123     params = collection_params(:foo_file, 'foo')
124     sess = session_for(:expired)
125     read_token = api_fixture('api_client_authorizations')['active']['api_token']
126     params[:reader_tokens] = [read_token]
127     get(:show_file, params, sess)
128     assert_response :success
129     assert_equal(expected_contents(params, read_token), @response.body,
130                  "failed to get a correct file from Keep using a reader token")
131     assert_not_equal(read_token, session[:arvados_api_token],
132                      "using a reader token set the session's API token")
133   end
134 end