1 require 'integration_helper'
2 require 'selenium-webdriver'
5 class CollectionsTest < ActionDispatch::IntegrationTest
7 Capybara.current_driver = :rack_test
10 # check_checkboxes_state asserts that the page holds at least one
11 # checkbox matching 'selector', and that all matching checkboxes
12 # are in state 'checkbox_status' (i.e. checked if true, unchecked otherwise)
13 def assert_checkboxes_state(selector, checkbox_status, msg=nil)
14 assert page.has_selector?(selector)
15 page.all(selector).each do |checkbox|
16 assert(checkbox.checked? == checkbox_status, msg)
20 test "Can copy a collection to a project" do
21 Capybara.current_driver = Capybara.javascript_driver
23 collection_uuid = api_fixture('collections')['foo_file']['uuid']
24 collection_name = api_fixture('collections')['foo_file']['name']
25 project_uuid = api_fixture('groups')['aproject']['uuid']
26 project_name = api_fixture('groups')['aproject']['name']
27 visit page_with_token('active', "/collections/#{collection_uuid}")
28 click_link 'Copy to project...'
29 find('.selectable', text: project_name).click
30 find('.modal-footer a,button', text: 'Copy').click
32 # It should navigate to the project after copying...
33 assert(page.has_text?(project_name))
34 assert(page.has_text?("Copy of #{collection_name}"))
37 test "Collection page renders name" do
38 uuid = api_fixture('collections')['foo_file']['uuid']
39 coll_name = api_fixture('collections')['foo_file']['name']
40 visit page_with_token('active', "/collections/#{uuid}")
41 assert(page.has_text?(coll_name), "Collection page did not include name")
42 # Now check that the page is otherwise normal, and the collection name
43 # isn't only showing up in an error message.
44 assert(page.has_link?('foo'), "Collection page did not include file link")
47 test "can download an entire collection with a reader token" do
48 CollectionsController.any_instance.
49 stubs(:file_enumerator).returns(["foo\n", "file\n"])
50 uuid = api_fixture('collections')['foo_file']['uuid']
51 token = api_fixture('api_client_authorizations')['active_all_collections']['api_token']
52 url_head = "/collections/download/#{uuid}/#{token}/"
54 # It seems that Capybara can't inspect tags outside the body, so this is
55 # a very blunt approach.
56 assert_no_match(/<\s*meta[^>]+\bnofollow\b/i, page.html,
57 "wget prohibited from recursing the collection page")
58 # Look at all the links that wget would recurse through using our
59 # recommended options, and check that it's exactly the file list.
60 hrefs = page.all('a').map do |anchor|
61 link = anchor[:href] || ''
62 if link.start_with? url_head
63 link[url_head.size .. -1]
64 elsif link.start_with? '/'
70 assert_equal(['foo'], hrefs.compact.sort,
71 "download page did provide strictly file links")
72 within "#collection_files" do
74 assert_equal("foo\nfile\n", page.html)
78 test "can view empty collection" do
79 uuid = 'd41d8cd98f00b204e9800998ecf8427e+0'
80 visit page_with_token('active', "/collections/#{uuid}")
81 assert page.has_text?('This collection is empty')
84 test "combine selected collections into new collection" do
85 headless = Headless.new
87 Capybara.current_driver = :selenium
89 foo_collection = api_fixture('collections')['foo_file']
90 bar_collection = api_fixture('collections')['bar_file']
92 visit page_with_token('active', "/collections")
94 assert(page.has_text?(foo_collection['uuid']), "Collection page did not include foo file")
95 assert(page.has_text?(bar_collection['uuid']), "Collection page did not include bar file")
97 within('tr', text: foo_collection['uuid']) do
98 find('input[type=checkbox]').click
101 within('tr', text: bar_collection['uuid']) do
102 find('input[type=checkbox]').click
105 click_button 'Selection...'
106 within('.selection-action-container') do
107 click_link 'Create new collection with selected collections'
110 # now in the newly created collection page
111 assert(page.has_text?('Copy to project'), "Copy to project text not found in new collection page")
112 assert(page.has_no_text?(foo_collection['name']), "Collection page did not include foo file")
113 assert(page.has_text?('foo'), "Collection page did not include foo file")
114 assert(page.has_no_text?(bar_collection['name']), "Collection page did not include foo file")
115 assert(page.has_text?('bar'), "Collection page did not include bar file")
116 assert(page.has_text?('Created new collection in your Home project'),
117 'Not found flash message that new collection is created in Home project')
122 ['active', 'foo_file', false],
123 ['active', 'foo_collection_in_aproject', true],
124 ['project_viewer', 'foo_file', false],
125 ['project_viewer', 'foo_collection_in_aproject', false], #aproject not writable
126 ].each do |user, collection, expect_collection_in_aproject|
127 test "combine selected collection files into new collection #{user} #{collection} #{expect_collection_in_aproject}" do
128 headless = Headless.new
130 Capybara.current_driver = :selenium
132 my_collection = api_fixture('collections')[collection]
134 visit page_with_token(user, "/collections")
136 # choose file from foo collection
137 within('tr', text: my_collection['uuid']) do
141 # now in collection page
142 find('input[type=checkbox]').click
144 click_button 'Selection...'
145 within('.selection-action-container') do
146 click_link 'Create new collection with selected files'
149 # now in the newly created collection page
150 assert(page.has_text?('Copy to project'), "Copy to project text not found in new collection page")
151 assert(page.has_no_text?(my_collection['name']), "Collection page did not include foo file")
152 assert(page.has_text?('foo'), "Collection page did not include foo file")
153 if expect_collection_in_aproject
154 aproject = api_fixture('groups')['aproject']
155 assert page.has_text?("Created new collection in the project #{aproject['name']}"),
156 'Not found flash message that new collection is created in aproject'
158 assert page.has_text?("Created new collection in your Home project"),
159 'Not found flash message that new collection is created in Home project'
166 test "combine selected collection files from collection subdirectory" do
167 headless = Headless.new
169 Capybara.current_driver = :selenium
171 visit page_with_token('user1_with_load', "/collections/zzzzz-4zz18-filesinsubdir00")
173 # now in collection page
174 input_files = page.all('input[type=checkbox]')
175 (0..input_files.count-1).each do |i|
179 click_button 'Selection...'
180 within('.selection-action-container') do
181 click_link 'Create new collection with selected files'
184 # now in the newly created collection page
185 assert(page.has_text?('file_in_subdir1'), 'file not found - file_in_subdir1')
186 assert(page.has_text?('file1_in_subdir3.txt'), 'file not found - file1_in_subdir3.txt')
187 assert(page.has_text?('file2_in_subdir3.txt'), 'file not found - file2_in_subdir3.txt')
188 assert(page.has_text?('file1_in_subdir4.txt'), 'file not found - file1_in_subdir4.txt')
189 assert(page.has_text?('file2_in_subdir4.txt'), 'file not found - file1_in_subdir4.txt')
194 test "Collection portable data hash redirect" do
195 di = api_fixture('collections')['docker_image']
196 visit page_with_token('active', "/collections/#{di['portable_data_hash']}")
199 assert current_path.end_with?("/collections/#{di['uuid']}")
200 assert page.has_text?("docker_image")
201 assert page.has_text?("Activity")
202 assert page.has_text?("Sharing and permissions")
205 test "Collection portable data hash with multiple matches" do
206 pdh = api_fixture('collections')['baz_file']['portable_data_hash']
207 visit page_with_token('admin', "/collections/#{pdh}")
209 matches = api_fixture('collections').select {|k,v| v["portable_data_hash"] == pdh}
210 assert matches.size > 1
212 matches.each do |k,v|
213 assert page.has_link?(v["name"]), "Page /collections/#{pdh} should contain link '#{v['name']}'"
215 assert page.has_no_text?("Activity")
216 assert page.has_no_text?("Sharing and permissions")
219 test "Filtering collection files by regexp" do
220 headless = Headless.new
222 Capybara.current_driver = :selenium
223 col = api_fixture('collections', 'multilevel_collection_1')
224 visit page_with_token('active', "/collections/#{col['uuid']}")
226 # Filter file list to some but not all files in the collection
227 page.find_field('file_regex').set('file[12]')
228 assert page.has_text?("file1")
229 assert page.has_text?("file2")
230 assert page.has_no_text?("file3")
232 # Filter file list with a regex matching all files
233 page.find_field('file_regex').set('.*')
234 assert page.has_text?("file1")
235 assert page.has_text?("file2")
236 assert page.has_text?("file3")
238 # Filter file list to a regex matching no files
239 page.find_field('file_regex').set('file9')
240 assert page.has_no_text?("file1")
241 assert page.has_no_text?("file2")
242 assert page.has_no_text?("file3")
243 # make sure that we actually are looking at the collections
244 # page and not e.g. a fiddlesticks
245 assert page.has_text?("multilevel_collection_1")
246 assert page.has_text?(col['portable_data_hash'])
248 # Set filename filter to a syntactically invalid regex
249 # Page loads, but stops filtering after the last valid regex parse
250 page.find_field('file_regex').set('file[2')
251 assert page.has_text?("multilevel_collection_1")
252 assert page.has_text?(col['portable_data_hash'])
253 assert page.has_text?("file1")
254 assert page.has_text?("file2")
255 assert page.has_text?("file3")
257 # Test the "Select all" button
259 # Note: calling .set('') on a Selenium element is not sufficient
260 # to reset the field for this test, as it does not send any key
261 # events to the browser. To clear the field, we must instead send
262 # a backspace character.
263 # See https://selenium.googlecode.com/svn/trunk/docs/api/rb/Selenium/WebDriver/Element.html#clear-instance_method
264 page.find_field('file_regex').set("\b") # backspace
265 find('button#select-all').click
266 assert_checkboxes_state('input[type=checkbox]', true, '"select all" should check all checkboxes')
268 # Test the "Unselect all" button
269 page.find_field('file_regex').set("\b") # backspace
270 find('button#unselect-all').click
271 assert_checkboxes_state('input[type=checkbox]', false, '"unselect all" should clear all checkboxes')
273 # Filter files, then "select all", then unfilter
274 page.find_field('file_regex').set("\b") # backspace
275 find('button#unselect-all').click
276 page.find_field('file_regex').set('file[12]')
277 find('button#select-all').click
278 page.find_field('file_regex').set("\b") # backspace
280 # all "file1" and "file2" checkboxes must be selected
281 # all "file3" checkboxes must be clear
282 assert_checkboxes_state('[value*="file1"]', true, 'checkboxes for file1 should be selected after filtering')
283 assert_checkboxes_state('[value*="file2"]', true, 'checkboxes for file2 should be selected after filtering')
284 assert_checkboxes_state('[value*="file3"]', false, 'checkboxes for file3 should be clear after filtering')
286 # Select all files, then filter, then "unselect all", then unfilter
287 page.find_field('file_regex').set("\b") # backspace
288 find('button#select-all').click
289 page.find_field('file_regex').set('file[12]')
290 find('button#unselect-all').click
291 page.find_field('file_regex').set("\b") # backspace
293 # all "file1" and "file2" checkboxes must be clear
294 # all "file3" checkboxes must be selected
295 assert_checkboxes_state('[value*="file1"]', false, 'checkboxes for file1 should be clear after filtering')
296 assert_checkboxes_state('[value*="file2"]', false, 'checkboxes for file2 should be clear after filtering')
297 assert_checkboxes_state('[value*="file3"]', true, 'checkboxes for file3 should be selected after filtering')
300 test "Creating collection from list of filtered files" do
301 headless = Headless.new
303 Capybara.current_driver = :selenium
305 col = api_fixture('collections', 'collection_with_files_in_subdir')
306 visit page_with_token('user1_with_load', "/collections/#{col['uuid']}")
307 assert page.has_text?('file_in_subdir1'), 'expected file_in_subdir1 not found'
308 assert page.has_text?('file1_in_subdir3'), 'expected file1_in_subdir3 not found'
309 assert page.has_text?('file2_in_subdir3'), 'expected file2_in_subdir3 not found'
310 assert page.has_text?('file1_in_subdir4'), 'expected file1_in_subdir4 not found'
311 assert page.has_text?('file2_in_subdir4'), 'expected file2_in_subdir4 not found'
313 # Select all files but then filter them to files in subdir1, subdir2 or subdir3
314 find('button#select-all').click
315 page.find_field('file_regex').set('_in_subdir[123]')
316 assert page.has_text?('file_in_subdir1'), 'expected file_in_subdir1 not in filtered files'
317 assert page.has_text?('file1_in_subdir3'), 'expected file1_in_subdir3 not in filtered files'
318 assert page.has_text?('file2_in_subdir3'), 'expected file2_in_subdir3 not in filtered files'
319 assert page.has_no_text?('file1_in_subdir4'), 'file1_in_subdir4 found in filtered files'
320 assert page.has_no_text?('file2_in_subdir4'), 'file2_in_subdir4 found in filtered files'
322 # Create a new collection
323 click_button 'Selection...'
324 within('.selection-action-container') do
325 click_link 'Create new collection with selected files'
328 # now in the newly created collection page
329 assert page.has_text?('Content hash:'), 'not on new collection page'
330 assert page.has_no_text?(col['uuid']), 'new collection page has old collection uuid'
331 assert page.has_no_text?(col['portable_data_hash']), 'new collection page has old portable_data_hash'
333 # must have files in subdir1 and subdir3 but not subdir4
334 assert page.has_text?('file_in_subdir1'), 'file_in_subdir1 missing from new collection'
335 assert page.has_text?('file1_in_subdir3'), 'file1_in_subdir3 missing from new collection'
336 assert page.has_text?('file2_in_subdir3'), 'file2_in_subdir3 missing from new collection'
337 assert page.has_no_text?('file1_in_subdir4'), 'file1_in_subdir4 found in new collection'
338 assert page.has_no_text?('file2_in_subdir4'), 'file2_in_subdir4 found in new collection'