require File.dirname(__FILE__) + '/../spec_helper' require 'rack/mock' def request(app, path) Rack::MockRequest.new(app).get(path) end describe Dragonfly::App do describe ".instance" do it "should create a new instance if it didn't already exist" do app = Dragonfly::App.instance(:images) app.should be_a(Dragonfly::App) end it "should return an existing instance if called by name" do app = Dragonfly::App.instance(:images) Dragonfly::App.instance(:images).should == app end it "should also work using square brackets" do Dragonfly[:images].should == Dragonfly::App.instance(:images) end end describe ".new" do it "should not be callable" do lambda{ Dragonfly::App.new }.should raise_error(NoMethodError) end end describe "mime types" do describe "#mime_type_for" do before(:each) do @app = test_app end it "should return the correct mime type for a symbol" do @app.mime_type_for(:png).should == 'image/png' end it "should work for strings" do @app.mime_type_for('png').should == 'image/png' end it "should work with uppercase strings" do @app.mime_type_for('PNG').should == 'image/png' end it "should work with a dot" do @app.mime_type_for('.png').should == 'image/png' end it "should return nil if not known" do @app.mime_type_for(:mark).should be_nil end it "should allow for configuring extra mime types" do @app.register_mime_type 'mark', 'application/mark' @app.mime_type_for(:mark).should == 'application/mark' end it "should override existing mime types when registered" do @app.register_mime_type :png, 'ping/pong' @app.mime_type_for(:png).should == 'ping/pong' end it "should have a per-app mime-type configuration" do other_app = Dragonfly[:other_app] @app.register_mime_type(:mark, 'first/one') other_app.register_mime_type(:mark, 'second/one') @app.mime_type_for(:mark).should == 'first/one' other_app.mime_type_for(:mark).should == 'second/one' end end describe "#resolve_mime_type" do before(:each) do @app = test_app @app.analyser.add :format do |temp_object| :png end @app.analyser.add :mime_type do |temp_object| 'image/jpeg' end @app.encoder.add do |temp_object| 'ENCODED DATA YO' end end it "should return the correct mime_type if the temp_object has a format" do temp_object = Dragonfly::TempObject.new("HIMATE", :format => :tiff, :name => 'test.pdf') @app.resolve_mime_type(temp_object).should == 'image/tiff' end it "should use the file extension if it has no format" do temp_object = Dragonfly::TempObject.new("HIMATE", :name => 'test.pdf') @app.resolve_mime_type(temp_object).should == 'application/pdf' end it "should not use the file extension if it's been switched off (fall back to mime_type analyser)" do @app.infer_mime_type_from_file_ext = false temp_object = Dragonfly::TempObject.new("HIMATE", :name => 'test.pdf') @app.resolve_mime_type(temp_object).should == 'image/jpeg' end it "should fall back to the mime_type analyser if the temp_object has no ext" do temp_object = Dragonfly::TempObject.new("HIMATE", :name => 'test') @app.resolve_mime_type(temp_object).should == 'image/jpeg' end describe "when the temp_object has no name" do before(:each) do @temp_object = Dragonfly::TempObject.new("HIMATE") end it "should fall back to the mime_type analyser" do @app.resolve_mime_type(@temp_object).should == 'image/jpeg' end it "should fall back to the format analyser if the mime_type analyser doesn't exist" do @app.analyser.functions.delete(:mime_type) @app.resolve_mime_type(@temp_object).should == 'image/png' end it "should fall back to the app's fallback mime_type if no mime_type/format analyser exists" do @app.analyser.functions.delete(:mime_type) @app.analyser.functions.delete(:format) @app.resolve_mime_type(@temp_object).should == 'application/octet-stream' end end end end describe "without path prefix or DOS protection" do before(:each) do @app = test_app @job = Dragonfly::Job.new(@app).fetch('some_uid') @app.datastore.stub!(:retrieve).with('some_uid').and_return "Hi there" @app.configure{|c| c.protect_from_dos_attacks = false } end it "should correctly respond with the job data" do response = request(@app, "/#{@job.serialize}") response.status.should == 200 response.body.should == "Hi there" end it "should generate the correct url" do @app.url_for(@job).should == "/#{@job.serialize}" end end describe "url_path_prefix" do before(:each) do @app = test_app @job = Dragonfly::Job.new(@app) end it "should add the path prefix to the url if configured" do @app.url_path_prefix = '/media' @app.url_for(@job).should =~ %r{^/media/\w+$} end it "should add the path prefix to the url if passed in" do @app.url_for(@job, :path_prefix => '/eggs').should =~ %r{^/eggs/\w+$} end it "should favour the passed in one" do @app.url_path_prefix = '/media' @app.url_for(@job, :path_prefix => '/bacon').should =~ %r{^/bacon/\w+$} end end describe "url_host" do before(:each) do @app = test_app @job = Dragonfly::Job.new(@app) end it "should add the host to the url if configured" do @app.url_host = 'http://some.server:4000' @app.url_for(@job).should =~ %r{^http://some\.server:4000/\w+$} end it "should add the host to the url if passed in" do @app.url_for(@job, :host => 'https://bungle.com').should =~ %r{^https://bungle\.com/\w+$} end it "should favour the passed in one" do @app.url_host = 'http://some.server:4000' @app.url_for(@job, :host => 'https://smeedy').should =~ %r{^https://smeedy/\w+$} end end describe "url_suffix" do before(:each) do @app = test_app @job = Dragonfly::Job.new(@app) end it "should add the suffix to the url if configured" do @app.url_suffix = 'hellodudes' @app.url_for(@job).should =~ /\w+hellodudes$/ end it "should add the suffix to the url if passed in" do @app.url_for(@job, :suffix => '/howdy.pardner').should =~ /\w+\/howdy\.pardner$/ end it "should favour the passed in one" do @app.url_suffix = 'hellodudes' @app.url_for(@job, :suffix => '/howdy.pardner').should =~ /\w+\/howdy\.pardner$/ end it "should accept a proc yielding the job" do @app.url_suffix = proc{|job| job.uid } @job.fetch!('some_uid') @app.url_for(@job).should =~ /\w+some_uid$/ end end describe "url params" do before(:each) do @app = test_app @job = Dragonfly::Job.new(@app) end it "should add extra params to the url query string" do @app.url_for(@job, :suffix => '/suffix', :a => 'thing', :b => 'nuther').should =~ /\w+\/suffix\?a=thing&b=nuther$/ end end describe "Denial of Service protection" do before(:each) do @app = test_app @app.protect_from_dos_attacks = true @job = Dragonfly::Job.new(@app).fetch('some_uid') end it "should generate the correct url" do @app.url_for(@job).should == "/#{@job.serialize}?s=#{@job.sha}" end end describe "configuring with saved configurations" do before(:each) do @app = test_app end { :imagemagick => Dragonfly::Config::ImageMagick, :image_magick => Dragonfly::Config::ImageMagick, :rmagick => Dragonfly::Config::RMagick, :r_magick => Dragonfly::Config::RMagick, :rails => Dragonfly::Config::Rails, :heroku => Dragonfly::Config::Heroku, }.each do |key, klass| it "should map #{key} to #{klass}" do klass.should_receive(:apply_configuration).with(@app) @app.configure_with(key) end end it "should description" do lambda { @app.configure_with(:eggs) }.should raise_error(ArgumentError) end end describe "#store" do before(:each) do @app = test_app end it "should allow just storing content" do @app.datastore.should_receive(:store).with(a_temp_object_with_data("HELLO"), {}) @app.store("HELLO") end it "should allow storing using a TempObject" do temp_object = Dragonfly::TempObject.new("HELLO") @app.datastore.should_receive(:store).with(temp_object, {}) @app.store(temp_object) end it "should allow storing with extra stuff" do @app.datastore.should_receive(:store).with( a_temp_object_with_data("HELLO", :meta => {:egg => :head}), {:option => :blarney} ) @app.store("HELLO", :meta => {:egg => :head}, :option => :blarney) end end end