Merge branch 'master' into 4091-test-infinite-scrolling
[arvados.git] / apps / workbench / test / integration / collections_test.rb
1 require 'integration_helper'
2 require 'selenium-webdriver'
3 require 'headless'
4
5 class CollectionsTest < ActionDispatch::IntegrationTest
6   setup do
7     Capybara.current_driver = :rack_test
8   end
9
10   test "Can copy a collection to a project" do
11     Capybara.current_driver = Capybara.javascript_driver
12
13     collection_uuid = api_fixture('collections')['foo_file']['uuid']
14     collection_name = api_fixture('collections')['foo_file']['name']
15     project_uuid = api_fixture('groups')['aproject']['uuid']
16     project_name = api_fixture('groups')['aproject']['name']
17     visit page_with_token('active', "/collections/#{collection_uuid}")
18     click_link 'Copy to project...'
19     find('.selectable', text: project_name).click
20     find('.modal-footer a,button', text: 'Copy').click
21     wait_for_ajax
22     # It should navigate to the project after copying...
23     assert(page.has_text?(project_name))
24     assert(page.has_text?("Copy of #{collection_name}"))
25   end
26
27   test "Collection page renders name" do
28     uuid = api_fixture('collections')['foo_file']['uuid']
29     coll_name = api_fixture('collections')['foo_file']['name']
30     visit page_with_token('active', "/collections/#{uuid}")
31     assert(page.has_text?(coll_name), "Collection page did not include name")
32     # Now check that the page is otherwise normal, and the collection name
33     # isn't only showing up in an error message.
34     assert(page.has_link?('foo'), "Collection page did not include file link")
35   end
36
37   test "can download an entire collection with a reader token" do
38     uuid = api_fixture('collections')['foo_file']['uuid']
39     token = api_fixture('api_client_authorizations')['active_all_collections']['api_token']
40     url_head = "/collections/download/#{uuid}/#{token}/"
41     visit url_head
42     # It seems that Capybara can't inspect tags outside the body, so this is
43     # a very blunt approach.
44     assert_no_match(/<\s*meta[^>]+\bnofollow\b/i, page.html,
45                     "wget prohibited from recursing the collection page")
46     # TODO: When we can test against a Keep server, actually follow links
47     # and check their contents, rather than testing the href directly
48     # (this is too closely tied to implementation details).
49     hrefs = page.all('a').map do |anchor|
50       link = anchor[:href] || ''
51       if link.start_with? url_head
52         link[url_head.size .. -1]
53       elsif link.start_with? '/'
54         nil
55       else
56         link
57       end
58     end
59     assert_equal(['foo'], hrefs.compact.sort,
60                  "download page did provide strictly file links")
61   end
62
63   test "can view empty collection" do
64     uuid = 'd41d8cd98f00b204e9800998ecf8427e+0'
65     visit page_with_token('active', "/collections/#{uuid}")
66     assert page.has_text?('This collection is empty')
67   end
68
69   test "combine selected collections into new collection" do
70     headless = Headless.new
71     headless.start
72     Capybara.current_driver = :selenium
73
74     foo_collection = api_fixture('collections')['foo_file']
75     bar_collection = api_fixture('collections')['bar_file']
76
77     visit page_with_token('active', "/collections")
78
79     assert(page.has_text?(foo_collection['uuid']), "Collection page did not include foo file")
80     assert(page.has_text?(bar_collection['uuid']), "Collection page did not include bar file")
81
82     within('tr', text: foo_collection['uuid']) do
83       find('input[type=checkbox]').click
84     end
85
86     within('tr', text: bar_collection['uuid']) do
87       find('input[type=checkbox]').click
88     end
89
90     click_button 'Selection...'
91     within('.selection-action-container') do
92       click_link 'Create new collection with selected collections'
93     end
94
95     # now in the newly created collection page
96     assert(page.has_text?('Copy to project'), "Copy to project text not found in new collection page")
97     assert(page.has_no_text?(foo_collection['name']), "Collection page did not include foo file")
98     assert(page.has_text?('foo'), "Collection page did not include foo file")
99     assert(page.has_no_text?(bar_collection['name']), "Collection page did not include foo file")
100     assert(page.has_text?('bar'), "Collection page did not include bar file")
101     assert(page.has_text?('Created new collection in your Home project'),
102                           'Not found flash message that new collection is created in Home project')
103     headless.stop
104   end
105
106   [
107     ['active', 'foo_file', false],
108     ['active', 'foo_collection_in_aproject', true],
109     ['project_viewer', 'foo_file', false],
110     ['project_viewer', 'foo_collection_in_aproject', false], #aproject not writable
111   ].each do |user, collection, expect_collection_in_aproject|
112     test "combine selected collection files into new collection #{user} #{collection} #{expect_collection_in_aproject}" do
113       headless = Headless.new
114       headless.start
115       Capybara.current_driver = :selenium
116
117       my_collection = api_fixture('collections')[collection]
118
119       visit page_with_token(user, "/collections")
120
121       # choose file from foo collection
122       within('tr', text: my_collection['uuid']) do
123         click_link 'Show'
124       end
125
126       # now in collection page
127       find('input[type=checkbox]').click
128
129       click_button 'Selection...'
130       within('.selection-action-container') do
131         click_link 'Create new collection with selected files'
132       end
133
134       # now in the newly created collection page
135       assert(page.has_text?('Copy to project'), "Copy to project text not found in new collection page")
136       assert(page.has_no_text?(my_collection['name']), "Collection page did not include foo file")
137       assert(page.has_text?('foo'), "Collection page did not include foo file")
138       if expect_collection_in_aproject
139         aproject = api_fixture('groups')['aproject']
140         assert page.has_text?("Created new collection in the project #{aproject['name']}"),
141                               'Not found flash message that new collection is created in aproject'
142       else
143         assert page.has_text?("Created new collection in your Home project"),
144                               'Not found flash message that new collection is created in Home project'
145       end
146
147       headless.stop
148     end
149   end
150
151   test "combine selected collection files from collection subdirectory" do
152     headless = Headless.new
153     headless.start
154     Capybara.current_driver = :selenium
155
156     visit page_with_token('user1_with_load', "/collections/zzzzz-4zz18-filesinsubdir00")
157
158     # now in collection page
159     input_files = page.all('input[type=checkbox]')
160     (0..input_files.count-1).each do |i|
161       input_files[i].click
162     end
163
164     click_button 'Selection...'
165     within('.selection-action-container') do
166       click_link 'Create new collection with selected files'
167     end
168
169     # now in the newly created collection page
170     assert(page.has_text?('file_in_subdir1'), 'file not found - file_in_subdir1')
171     assert(page.has_text?('file1_in_subdir3.txt'), 'file not found - file1_in_subdir3.txt')
172     assert(page.has_text?('file2_in_subdir3.txt'), 'file not found - file2_in_subdir3.txt')
173     assert(page.has_text?('file1_in_subdir4.txt'), 'file not found - file1_in_subdir4.txt')
174     assert(page.has_text?('file2_in_subdir4.txt'), 'file not found - file1_in_subdir4.txt')
175
176     headless.stop
177   end
178
179   test "Collection portable data hash redirect" do
180     di = api_fixture('collections')['docker_image']
181     visit page_with_token('active', "/collections/#{di['portable_data_hash']}")
182
183     # check redirection
184     assert current_path.end_with?("/collections/#{di['uuid']}")
185     assert page.has_text?("docker_image")
186     assert page.has_text?("Activity")
187     assert page.has_text?("Sharing and permissions")
188   end
189
190   test "Collection portable data hash with multiple matches" do
191     pdh = api_fixture('collections')['baz_file']['portable_data_hash']
192     visit page_with_token('admin', "/collections/#{pdh}")
193
194     matches = api_fixture('collections').select {|k,v| v["portable_data_hash"] == pdh}
195     assert matches.size > 1
196
197     matches.each do |k,v|
198       assert page.has_link?(v["name"]), "Page /collections/#{pdh} should contain link '#{v['name']}'"
199     end
200     assert page.has_no_text?("Activity")
201     assert page.has_no_text?("Sharing and permissions")
202   end
203
204   test "Filtering collection files by regexp" do
205     col = api_fixture('collections', 'multilevel_collection_1')
206     visit page_with_token('active', "/collections/#{col['uuid']}")
207
208     # Test when only some files match the regex
209     page.find_field('file_regex').set('file[12]')
210     find('button#file_regex_submit').click
211     assert page.has_text?("file1")
212     assert page.has_text?("file2")
213     assert page.has_no_text?("file3")
214
215     # Test all files matching the regex
216     page.find_field('file_regex').set('file[123]')
217     find('button#file_regex_submit').click
218     assert page.has_text?("file1")
219     assert page.has_text?("file2")
220     assert page.has_text?("file3")
221
222     # Test no files matching the regex
223     page.find_field('file_regex').set('file9')
224     find('button#file_regex_submit').click
225     assert page.has_no_text?("file1")
226     assert page.has_no_text?("file2")
227     assert page.has_no_text?("file3")
228     # make sure that we actually are looking at the collections
229     # page and not e.g. a fiddlesticks
230     assert page.has_text?("multilevel_collection_1")
231     assert page.has_text?(col['portable_data_hash'])
232
233     # Syntactically invalid regex
234     # Page loads, but does not match any files
235     page.find_field('file_regex').set('file[2')
236     find('button#file_regex_submit').click
237     assert page.has_text?('could not be parsed as a regular expression')
238     assert page.has_no_text?("file1")
239     assert page.has_no_text?("file2")
240     assert page.has_no_text?("file3")
241   end
242 end