Merge branch 'master' into 4523-search-index
[arvados.git] / services / api / test / integration / collections_api_test.rb
1 require 'test_helper'
2
3 class CollectionsApiTest < ActionDispatch::IntegrationTest
4   fixtures :all
5
6   test "should get index" do
7     get "/arvados/v1/collections", {:format => :json}, auth(:active)
8     assert_response :success
9     assert_equal "arvados#collectionList", json_response['kind']
10   end
11
12   test "get index with filters= (empty string)" do
13     get "/arvados/v1/collections", {:format => :json, :filters => ''}, auth(:active)
14     assert_response :success
15     assert_equal "arvados#collectionList", json_response['kind']
16   end
17
18   test "get index with invalid filters (array of strings) responds 422" do
19     get "/arvados/v1/collections", {
20       :format => :json,
21       :filters => ['uuid', '=', 'ad02e37b6a7f45bbe2ead3c29a109b8a+54'].to_json
22     }, auth(:active)
23     assert_response 422
24     assert_match /nvalid element.*not an array/, json_response['errors'].join(' ')
25   end
26
27   test "get index with invalid filters (unsearchable column) responds 422" do
28     get "/arvados/v1/collections", {
29       :format => :json,
30       :filters => [['this_column_does_not_exist', '=', 'bogus']].to_json
31     }, auth(:active)
32     assert_response 422
33     assert_match /nvalid attribute/, json_response['errors'].join(' ')
34   end
35
36   test "get index with invalid filters (invalid operator) responds 422" do
37     get "/arvados/v1/collections", {
38       :format => :json,
39       :filters => [['uuid', ':-(', 'displeased']].to_json
40     }, auth(:active)
41     assert_response 422
42     assert_match /nvalid operator/, json_response['errors'].join(' ')
43   end
44
45   test "get index with invalid filters (invalid operand type) responds 422" do
46     get "/arvados/v1/collections", {
47       :format => :json,
48       :filters => [['uuid', '=', {foo: 'bar'}]].to_json
49     }, auth(:active)
50     assert_response 422
51     assert_match /nvalid operand type/, json_response['errors'].join(' ')
52   end
53
54   test "get index with where= (empty string)" do
55     get "/arvados/v1/collections", {:format => :json, :where => ''}, auth(:active)
56     assert_response :success
57     assert_equal "arvados#collectionList", json_response['kind']
58   end
59
60   test "controller 404 response is json" do
61     get "/arvados/v1/thingsthatdonotexist", {:format => :xml}, auth(:active)
62     assert_response 404
63     assert_equal 1, json_response['errors'].length
64     assert_equal true, json_response['errors'][0].is_a?(String)
65   end
66
67   test "object 404 response is json" do
68     get "/arvados/v1/groups/zzzzz-j7d0g-o5ba971173cup4f", {}, auth(:active)
69     assert_response 404
70     assert_equal 1, json_response['errors'].length
71     assert_equal true, json_response['errors'][0].is_a?(String)
72   end
73
74   test "store collection as json" do
75     signing_opts = {
76       key: Rails.configuration.blob_signing_key,
77       api_token: api_token(:active),
78     }
79     signed_locator = Blob.sign_locator('bad42fa702ae3ea7d888fef11b46f450+44',
80                                        signing_opts)
81     post "/arvados/v1/collections", {
82       format: :json,
83       collection: "{\"manifest_text\":\". #{signed_locator} 0:44:md5sum.txt\\n\",\"portable_data_hash\":\"ad02e37b6a7f45bbe2ead3c29a109b8a+54\"}"
84     }, auth(:active)
85     assert_response 200
86     assert_equal 'ad02e37b6a7f45bbe2ead3c29a109b8a+54', json_response['portable_data_hash']
87   end
88
89   test "store collection with manifest_text only" do
90     signing_opts = {
91       key: Rails.configuration.blob_signing_key,
92       api_token: api_token(:active),
93     }
94     signed_locator = Blob.sign_locator('bad42fa702ae3ea7d888fef11b46f450+44',
95                                        signing_opts)
96     post "/arvados/v1/collections", {
97       format: :json,
98       collection: "{\"manifest_text\":\". #{signed_locator} 0:44:md5sum.txt\\n\"}"
99     }, auth(:active)
100     assert_response 200
101     assert_equal 'ad02e37b6a7f45bbe2ead3c29a109b8a+54', json_response['portable_data_hash']
102   end
103
104   test "store collection then update name" do
105     signing_opts = {
106       key: Rails.configuration.blob_signing_key,
107       api_token: api_token(:active),
108     }
109     signed_locator = Blob.sign_locator('bad42fa702ae3ea7d888fef11b46f450+44',
110                                        signing_opts)
111     post "/arvados/v1/collections", {
112       format: :json,
113       collection: "{\"manifest_text\":\". #{signed_locator} 0:44:md5sum.txt\\n\",\"portable_data_hash\":\"ad02e37b6a7f45bbe2ead3c29a109b8a+54\"}"
114     }, auth(:active)
115     assert_response 200
116     assert_equal 'ad02e37b6a7f45bbe2ead3c29a109b8a+54', json_response['portable_data_hash']
117
118     put "/arvados/v1/collections/#{json_response['uuid']}", {
119       format: :json,
120       collection: { name: "a name" }
121     }, auth(:active)
122
123     assert_response 200
124     assert_equal 'ad02e37b6a7f45bbe2ead3c29a109b8a+54', json_response['portable_data_hash']
125     assert_equal 'a name', json_response['name']
126
127     get "/arvados/v1/collections/#{json_response['uuid']}", {
128       format: :json,
129     }, auth(:active)
130
131     assert_response 200
132     assert_equal 'ad02e37b6a7f45bbe2ead3c29a109b8a+54', json_response['portable_data_hash']
133     assert_equal 'a name', json_response['name']
134   end
135
136   test "create collection, update description, and search for description" do
137     signing_opts = {
138       key: Rails.configuration.blob_signing_key,
139       api_token: api_token(:active),
140     }
141     signed_locator = Blob.sign_locator('bad42fa702ae1234d999fef11b46f450+44', signing_opts)
142
143     # create collection
144     post "/arvados/v1/collections", {
145       format: :json,
146       collection: "{\"manifest_text\":\". #{signed_locator} 0:44:foo.txt\\n\"}"
147     }, auth(:active)
148     assert_response :success
149     assert_equal '087e2f211aba2881c08fd8d1646522a3+51', json_response['portable_data_hash']
150
151     # update collection's description
152     put "/arvados/v1/collections/#{json_response['uuid']}", {
153       format: :json,
154       collection: { description: "something specific" }
155     }, auth(:active)
156     assert_response :success
157     assert_equal 'something specific', json_response['description']
158     assert_equal '087e2f211aba2881c08fd8d1646522a3+51', json_response['portable_data_hash']
159
160     # search
161     search_using_filter 'specific', 1, '087e2f211aba2881c08fd8d1646522a3+51'
162     search_using_filter 'not specific enough', 0, nil
163   end
164
165   test "create collection, update manifest, and search with filename" do
166     signing_opts = {
167       key: Rails.configuration.blob_signing_key,
168       api_token: api_token(:active),
169     }
170     signed_locator = Blob.sign_locator('bad42fa702ae3ea7d999fef11b46f450+44', signing_opts)
171
172     # create collection
173     post "/arvados/v1/collections", {
174       format: :json,
175       collection: "{\"manifest_text\":\". #{signed_locator} 0:44:my_test_file.txt\\n\"}"
176     }, auth(:active)
177     assert_response :success
178     assert_equal true, json_response['manifest_text'].include?('my_test_file.txt')
179     assert_equal '0f99f4087beb13dec46d36db9fa6cebf+60', json_response['portable_data_hash']
180
181     created = json_response
182
183     # search using the filename
184     search_using_filter 'my_test_file.txt', 1, '0f99f4087beb13dec46d36db9fa6cebf+60'
185
186     # update the collection's manifest text
187     put "/arvados/v1/collections/#{created['uuid']}", {
188       format: :json,
189       collection: "{\"manifest_text\":\". #{signed_locator} 0:44:my_updated_test_file.txt\\n\"}"
190     }, auth(:active)
191     assert_response :success
192     assert_equal created['uuid'], json_response['uuid']
193     assert_equal true, json_response['manifest_text'].include?('my_updated_test_file.txt')
194     assert_equal false, json_response['manifest_text'].include?('my_test_file.txt')
195
196     # search using the new filename
197     search_using_filter 'my_updated_test_file.txt', 1, '17d7d7e6f09ae17e3b580143586a1a3f+68'
198     search_using_filter 'my_test_file.txt', 0, nil
199     search_using_filter 'there_is_no_such_file.txt', 0, nil
200   end
201
202   def search_using_filter search_filter, expected_items, pdh
203     get '/arvados/v1/collections', {
204       where: { any: ['contains', search_filter] }
205     }, auth(:active)
206     assert_response :success
207     response_items = json_response['items']
208     assert_not_nil response_items
209     if expected_items == 0
210       assert_equal 0, json_response['items_available']
211       assert_equal 0, response_items.size
212     else
213       assert_equal expected_items, response_items.size
214       first_item = response_items.first
215       assert_not_nil first_item
216       assert_equal pdh, first_item['portable_data_hash']
217     end
218   end
219 end