1
votes

I am trying to write a rails test (Using Capybara & Poltergeist) to test .zip file download functionality.

I have the binary data of a .zip file being returned from an XHR request and I am hoping to write this data into a .zip file locally and carry out further tests from there.
The following method emulates a click on a button which, when in-app, returns a zip file of all the files that have been selected:

# Perform XHR
def download_file(link)
  page.execute_script("window.downloadFile = function(){ var url = window.location.protocol + '//' + window.location.host + '#{link}'; return getFile(url); }")
  page.execute_script("window.getFile = function(url){ var xhr = new XMLHttpRequest(); xhr.open('GET', url, false); xhr.responseType = 'blob'; xhr.send(); return xhr.response; }")

  begin
    file = page.evaluate_script('downloadFile()')
  rescue
    raise "Error during XHR. Is url valid?"
  end
  file
end

I am trying to write the response to file here:

file = download_file(url)
file_path = "#{Rails.root}/tmp/files/download.zip"
File.open(file_path, 'wb'){ |f| f.write file }

When trying to unzip the resulting file using unzip tmp/files/download.zip I'm given the following response:

Archive:  tmp/files/download.zip

caution:  zipfile comment truncated
error [tmp/files/download.zip]:  missing 3182550208 bytes in zipfile
  (attempting to process anyway)
error [tmp/files/download.zip]:  start of central directory not found;
  zipfile corrupt.
  (please check that you have transferred or created the zipfile in the
  appropriate BINARY mode and that you have compiled UnZip properly)

I have tried overriding the MIME type to text/plain, application/zip etc. but to no avail.
Any suggestions?

1

1 Answers

0
votes

I extended the Tempfile class to include a write binary function

class Tempfile
    def openBinary
        @tmpfile.close if @tmpfile
        @tmpfile = File.open(@tmpname, 'wb')
        @data[1] = @tmpfile
        __setobj__(@tmpfile)
   end
end

This made it possible for my system to parse zip files and then read the using Zip::ZipFile class.