Merge branch '1968-monitor-disk-usage'
[arvados.git] / services / api / test / functional / arvados / v1 / links_controller_test.rb
1 require 'test_helper'
2
3 class Arvados::V1::LinksControllerTest < ActionController::TestCase
4
5   test "no symbol keys in serialized hash" do
6     link = {
7       properties: {username: 'testusername'},
8       link_class: 'test',
9       name: 'encoding',
10       tail_uuid: users(:admin).uuid,
11       head_uuid: virtual_machines(:testvm).uuid
12     }
13     authorize_with :admin
14     [link, link.to_json].each do |formatted_link|
15       post :create, link: formatted_link
16       assert_response :success
17       assert_not_nil assigns(:object)
18       assert_equal 'testusername', assigns(:object).properties['username']
19       assert_equal false, assigns(:object).properties.has_key?(:username)
20     end
21   end
22
23   %w(created_at modified_at).each do |attr|
24     {nil: nil, bogus: 2.days.ago}.each do |bogustype, bogusvalue|
25       test "cannot set #{bogustype} #{attr} in create" do
26         authorize_with :active
27         post :create, {
28           link: {
29             properties: {},
30             link_class: 'test',
31             name: 'test',
32           }.merge(attr => bogusvalue)
33         }
34         assert_response :success
35         resp = JSON.parse @response.body
36         assert_in_delta Time.now, Time.parse(resp[attr]), 3.0
37       end
38       test "cannot set #{bogustype} #{attr} in update" do
39         really_created_at = links(:test_timestamps).created_at
40         authorize_with :active
41         put :update, {
42           id: links(:test_timestamps).uuid,
43           link: {
44             :properties => {test: 'test'},
45             attr => bogusvalue
46           }
47         }
48         assert_response :success
49         resp = JSON.parse @response.body
50         case attr
51         when 'created_at'
52           assert_in_delta really_created_at, Time.parse(resp[attr]), 0.001
53         else
54           assert_in_delta Time.now, Time.parse(resp[attr]), 3.0
55         end
56       end
57     end
58   end
59
60   test "head must exist" do
61     link = {
62       link_class: 'test',
63       name: 'stuff',
64       tail_uuid: users(:active).uuid,
65       head_uuid: 'zzzzz-tpzed-xyzxyzxerrrorxx'
66     }
67     authorize_with :admin
68     post :create, link: link
69     assert_response 422
70   end
71
72   test "tail must exist" do
73     link = {
74       link_class: 'test',
75       name: 'stuff',
76       head_uuid: users(:active).uuid,
77       tail_uuid: 'zzzzz-tpzed-xyzxyzxerrrorxx'
78     }
79     authorize_with :admin
80     post :create, link: link
81     assert_response 422
82   end
83
84   test "head and tail exist, head_kind and tail_kind are returned" do
85     link = {
86       link_class: 'test',
87       name: 'stuff',
88       head_uuid: users(:active).uuid,
89       tail_uuid: users(:spectator).uuid,
90     }
91     authorize_with :admin
92     post :create, link: link
93     assert_response :success
94     l = JSON.parse(@response.body)
95     assert 'arvados#user', l['head_kind']
96     assert 'arvados#user', l['tail_kind']
97   end
98
99   test "can supply head_kind and tail_kind without error" do
100     link = {
101       link_class: 'test',
102       name: 'stuff',
103       head_uuid: users(:active).uuid,
104       tail_uuid: users(:spectator).uuid,
105       head_kind: "arvados#user",
106       tail_kind: "arvados#user",
107     }
108     authorize_with :admin
109     post :create, link: link
110     assert_response :success
111     l = JSON.parse(@response.body)
112     assert 'arvados#user', l['head_kind']
113     assert 'arvados#user', l['tail_kind']
114   end
115
116   test "tail must be visible by user" do
117     link = {
118       link_class: 'test',
119       name: 'stuff',
120       head_uuid: users(:active).uuid,
121       tail_uuid: virtual_machines(:testvm).uuid
122     }
123     authorize_with :active
124     post :create, link: link
125     assert_response 422
126   end
127
128   test "filter links with 'is_a' operator" do
129     authorize_with :admin
130     get :index, {
131       filters: [ ['tail_uuid', 'is_a', 'arvados#user'] ]
132     }
133     assert_response :success
134     found = assigns(:objects)
135     assert_not_equal 0, found.count
136     assert_equal found.count, (found.select { |f| f.tail_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
137   end
138
139   test "filter links with 'is_a' operator with more than one" do
140     authorize_with :admin
141     get :index, {
142       filters: [ ['tail_uuid', 'is_a', ['arvados#user', 'arvados#group'] ] ],
143     }
144     assert_response :success
145     found = assigns(:objects)
146     assert_not_equal 0, found.count
147     assert_equal found.count, (found.select { |f| f.tail_uuid.match /[a-z0-9]{5}-(tpzed|j7d0g)-[a-z0-9]{15}/}).count
148   end
149
150   test "filter links with 'is_a' operator with bogus type" do
151     authorize_with :admin
152     get :index, {
153       filters: [ ['tail_uuid', 'is_a', ['arvados#bogus'] ] ],
154     }
155     assert_response :success
156     found = assigns(:objects)
157     assert_equal 0, found.count
158   end
159
160   test "filter links with 'is_a' operator with collection" do
161     authorize_with :admin
162     get :index, {
163       filters: [ ['head_uuid', 'is_a', ['arvados#collection'] ] ],
164     }
165     assert_response :success
166     found = assigns(:objects)
167     assert_not_equal 0, found.count
168     assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-f0-9]{32}\+\d+/}).count
169   end
170
171   test "test can still use where tail_kind" do
172     authorize_with :admin
173     get :index, {
174       where: { tail_kind: 'arvados#user' }
175     }
176     assert_response :success
177     found = assigns(:objects)
178     assert_not_equal 0, found.count
179     assert_equal found.count, (found.select { |f| f.tail_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
180   end
181
182   test "test can still use where head_kind" do
183     authorize_with :admin
184     get :index, {
185       where: { head_kind: 'arvados#user' }
186     }
187     assert_response :success
188     found = assigns(:objects)
189     assert_not_equal 0, found.count
190     assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
191   end
192
193   test "test can still use filter tail_kind" do
194     authorize_with :admin
195     get :index, {
196       filters: [ ['tail_kind', '=', 'arvados#user'] ]
197     }
198     assert_response :success
199     found = assigns(:objects)
200     assert_not_equal 0, found.count
201     assert_equal found.count, (found.select { |f| f.tail_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
202   end
203
204   test "test can still use filter head_kind" do
205     authorize_with :admin
206     get :index, {
207       filters: [ ['head_kind', '=', 'arvados#user'] ]
208     }
209     assert_response :success
210     found = assigns(:objects)
211     assert_not_equal 0, found.count
212     assert_equal found.count, (found.select { |f| f.head_uuid.match /[a-z0-9]{5}-tpzed-[a-z0-9]{15}/}).count
213   end
214
215   test "head_kind matches head_uuid" do
216     link = {
217       link_class: 'test',
218       name: 'stuff',
219       head_uuid: groups(:public).uuid,
220       head_kind: "arvados#user",
221       tail_uuid: users(:spectator).uuid,
222       tail_kind: "arvados#user",
223     }
224     authorize_with :admin
225     post :create, link: link
226     assert_response 422
227   end
228
229   test "tail_kind matches tail_uuid" do
230     link = {
231       link_class: 'test',
232       name: 'stuff',
233       head_uuid: users(:active).uuid,
234       head_kind: "arvados#user",
235       tail_uuid: groups(:public).uuid,
236       tail_kind: "arvados#user",
237     }
238     authorize_with :admin
239     post :create, link: link
240     assert_response 422
241   end
242
243   test "test with virtual_machine" do
244     link = {
245       tail_kind: "arvados#user",
246       tail_uuid: users(:active).uuid,
247       head_kind: "arvados#virtual_machine",
248       head_uuid: virtual_machines(:testvm).uuid,
249       link_class: "permission",
250       name: "can_login",
251       properties: {username: "repo_and_user_name"}
252     }
253     authorize_with :admin
254     post :create, link: link
255     assert_response 422
256   end
257
258   test "test with virtualMachine" do
259     link = {
260       tail_kind: "arvados#user",
261       tail_uuid: users(:active).uuid,
262       head_kind: "arvados#virtualMachine",
263       head_uuid: virtual_machines(:testvm).uuid,
264       link_class: "permission",
265       name: "can_login",
266       properties: {username: "repo_and_user_name"}
267     }
268     authorize_with :admin
269     post :create, link: link
270     assert_response :success
271   end
272
273   test "refuse duplicate name" do
274     the_name = links(:job_name_in_afolder).name
275     the_folder = links(:job_name_in_afolder).tail_uuid
276     authorize_with :active
277     post :create, link: {
278       tail_uuid: the_folder,
279       head_uuid: specimens(:owned_by_active_user).uuid,
280       link_class: 'name',
281       name: the_name,
282       properties: {this_s: "a duplicate name"}
283     }
284     assert_response 422
285   end
286 end