# frozen_string_literal: true require 'rails_helper' require 'file_helper' describe FileHelper do let(:url) { "https://eviltrout.com/trout.png" } let(:png) { File.read("#{Rails.root}/spec/fixtures/images/cropped.png") } before do stub_request(:any, /https:\/\/eviltrout.com/) stub_request(:get, url).to_return(body: png) end describe "download" do it "correctly raises an OpenURI HTTP error if it gets a 404 even with redirect" do url = "http://fourohfour.com/404" stub_request(:get, url).to_return(status: 404, body: "404") expect do begin FileHelper.download( url, max_file_size: 10000, tmp_file_name: 'trouttmp', follow_redirect: true ) rescue => e expect(e.io.status[0]).to eq("404") raise end end.to raise_error(OpenURI::HTTPError, "404 Error: 404") end it "does not follow redirects if instructed not to" do url2 = "https://test.com/image.png" stub_request(:get, url).to_return(status: 302, body: "", headers: { location: url2 }) missing = FileHelper.download( url, max_file_size: 10000, tmp_file_name: 'trouttmp', follow_redirect: false ) expect(missing).to eq(nil) end it "does follow redirects if instructed to" do url2 = "https://test.com/image.png" stub_request(:get, url).to_return(status: 302, body: "", headers: { location: url2 }) stub_request(:get, url2).to_return(status: 200, body: "i am the body") begin found = FileHelper.download( url, max_file_size: 10000, tmp_file_name: 'trouttmp', follow_redirect: true ) expect(found.read).to eq("i am the body") ensure found&.close found&.unlink end end it "correctly raises an OpenURI HTTP error if it gets a 404" do url = "http://fourohfour.com/404" stub_request(:get, url).to_return(status: 404, body: "404") expect do begin FileHelper.download( url, max_file_size: 10000, tmp_file_name: 'trouttmp', follow_redirect: false ) rescue => e expect(e.io.status[0]).to eq("404") raise end end.to raise_error(OpenURI::HTTPError) end it "returns a file with the image" do begin tmpfile = FileHelper.download( url, max_file_size: 10000, tmp_file_name: 'trouttmp' ) expect(Base64.encode64(tmpfile.read)).to eq(Base64.encode64(png)) ensure tmpfile&.close tmpfile&.unlink end end it "works with a protocol relative url" do begin tmpfile = FileHelper.download( "//eviltrout.com/trout.png", max_file_size: 10000, tmp_file_name: 'trouttmp' ) expect(Base64.encode64(tmpfile.read)).to eq(Base64.encode64(png)) ensure tmpfile&.close tmpfile&.unlink end end describe 'when max_file_size is exceeded' do it 'should return nil' do tmpfile = FileHelper.download( "//eviltrout.com/trout.png", max_file_size: 1, tmp_file_name: 'trouttmp' ) expect(tmpfile).to eq(nil) end it 'is able to retain the tmpfile' do begin tmpfile = FileHelper.download( "//eviltrout.com/trout.png", max_file_size: 1, tmp_file_name: 'trouttmp', retain_on_max_file_size_exceeded: true ) expect(tmpfile.closed?).to eq(false) ensure tmpfile&.close tmpfile&.unlink end end end describe 'when url is a jpeg' do let(:url) { "https://eviltrout.com/trout.jpg" } it "should prioritize the content type returned by the response" do begin stub_request(:get, url).to_return(body: png, headers: { "content-type": "image/png" }) tmpfile = FileHelper.download( url, max_file_size: 10000, tmp_file_name: 'trouttmp' ) expect(File.extname(tmpfile)).to eq('.png') ensure tmpfile&.close tmpfile&.unlink end end end end end