Permalink
Browse files

Added feature for downloading non-processed and non-encoded files.

* url handler now requires the path to begin with a slash
* parameters doesn't validate for uid and format any more (was a bit useless)
* you can pass format nil to create a url with no extension and it will work
  • Loading branch information...
1 parent 314dda0 commit a2cdb40f2756b4861345da08ce0cd3f69a1e8118 Mark Evans committed Nov 20, 2009
@@ -3,34 +3,35 @@ Feature: champion uses dragonfly to process images
A user uses dragonfly
Background:
+ Given we are using the app for images
Given a stored image "beach.png" with dimensions 200x100
Scenario: Go to url for original
- When I go to the url for image "beach.png", with format 'png'
+ When I go to the url for "beach.png", with format 'png'
Then the response should be OK
And the response should have mime-type 'image/png'
And the image should have width '200'
And the image should have height '100'
And the image should have format 'png'
Scenario: Go to url for changed format version
- When I go to the url for image "beach.png", with format 'gif'
+ When I go to the url for "beach.png", with format 'gif'
Then the response should be OK
And the response should have mime-type 'image/gif'
And the image should have width '200'
And the image should have height '100'
And the image should have format 'gif'
Scenario: Go to url for soft resized version
- When I go to the url for image "beach.png", with format 'png' and resize geometry '100x150'
+ When I go to the url for "beach.png", with format 'png' and resize geometry '100x150'
Then the response should be OK
And the response should have mime-type 'image/png'
And the image should have width '100'
And the image should have height '50'
And the image should have format 'png'
Scenario: Go to url for hard resized version
- When I go to the url for image "beach.png", with format 'png' and resize geometry '100x150!'
+ When I go to the url for "beach.png", with format 'png' and resize geometry '100x150!'
Then the response should be OK
And the response should have mime-type 'image/png'
And the image should have width '100'
@@ -0,0 +1,20 @@
+Feature: winner uses dragonfly to serve different kinds of files
+ In order to be a winner
+ As a potential loser
+ I want to be a winner
+
+ Background:
+ Given we are using the app for files
+
+ Scenario: Go to url for original, without extension
+ Given a stored file "sample.docx"
+ When I go to the url for "sample.docx"
+ Then the response should be OK
+ And the response should have mime-type 'application/zip'
+ And the response should have the same content as the file "sample.docx"
+
+ Scenario: Go to url for original, with extension
+ Given a stored file "sample.docx"
+ When I go to the url for "sample.docx", with format 'docx'
+ Then the response should be OK
+ And the response should have mime-type 'application/zip'
@@ -1,17 +1,30 @@
+Given /^we are using the app for (\w+)$/ do |app_name|
+ $app = Dragonfly::App[app_name.to_sym]
+end
+
+Given /^a stored file "(.+?)"$/ do |name|
+ file = File.new(File.dirname(__FILE__) + "/../../samples/#{name}")
+ uid = $app.store(file)
+ TEMP_FILES[name] = uid
+end
+
Given /^a stored image "(.+?)" with dimensions (\d+)x(\d+)$/ do |name, width, height|
tempfile = Tempfile.new(name)
`convert -resize #{width}x#{height}! #{SAMPLE_IMAGE_PATH} #{tempfile.path}`
- temp_object = APP.create_object(tempfile)
- uid = APP.datastore.store(temp_object)
- TEMP_IMAGES[name] = uid
+ uid = $app.store(tempfile)
+ TEMP_FILES[name] = uid
end
-When /^I go to the url for image "(.+?)", with format '([^']+?)'$/ do |name, ext|
- make_image_request name, :format => ext
+When /^I go to the url for "(.+?)"$/ do |name|
+ make_request name
end
-When /^I go to the url for image "(.+?)", with format '(.+?)' and resize geometry '(.+?)'$/ do |name, ext, geometry|
- make_image_request(name,
+When /^I go to the url for "(.+?)", with format '([^']+?)'$/ do |name, ext|
+ make_request name, :format => ext
+end
+
+When /^I go to the url for "(.+?)", with format '(.+?)' and resize geometry '(.+?)'$/ do |name, ext, geometry|
+ make_request(name,
:format => ext,
:processing_method => :resize,
:processing_options => {:geometry => geometry}
@@ -22,7 +35,7 @@
@response.status.should == 200
end
-Then "the response should have mime-type '(.+?)'" do |mime_type|
+Then /the response should have mime-type '(.+?)'/ do |mime_type|
@response.headers['Content-Type'].should == mime_type
end
@@ -37,3 +50,7 @@
Then "the image should have format '(.+?)'" do |format|
@response.body.should have_format(format)
end
+
+Then /^the response should have the same content as the file "([^\"]*)"$/ do |name|
+ @response.body.should == $app.fetch(TEMP_FILES[name]).data
+end
View
@@ -3,23 +3,32 @@
require 'spec/expectations'
require 'test/unit/assertions'
require 'ruby-debug'
-require File.dirname(__FILE__) + '/image_helpers.rb'
require File.dirname(__FILE__) + '/../../spec/image_matchers.rb'
# A hash of <name for reference> => <dragonfly uid> pairs
-TEMP_IMAGES = {}
+TEMP_FILES = {}
-APP = Dragonfly::App[:images]
-APP.configure_with(Dragonfly::RMagickConfiguration)
+Dragonfly::App[:images].configure_with(Dragonfly::RMagickConfiguration)
+Dragonfly::App[:files].analyser.register(Dragonfly::Analysis::FileCommandAnalyser.new)
SAMPLE_IMAGE_PATH = File.dirname(__FILE__)+'/../../samples/beach.png'
Before do
# Remove temporary images
- TEMP_IMAGES.each do |name, uid|
- APP.datastore.destroy(uid)
- TEMP_IMAGES.delete(name)
+ TEMP_FILES.each do |name, uid|
+ $app.datastore.destroy(uid)
+ TEMP_FILES.delete(name)
end
end
-World(ImageHelpers)
+module MyHelpers
+
+ def make_request(name, parameters = {})
+ request = Rack::MockRequest.new($app)
+ url = $app.url_handler.url_for(TEMP_FILES[name], parameters)
+ @response = request.get(url)
+ end
+
+end
+
+World(MyHelpers)
@@ -1,9 +0,0 @@
-module ImageHelpers
-
- def make_image_request(name, parameters = {})
- request = Rack::MockRequest.new(APP)
- url = APP.url_handler.url_for(TEMP_IMAGES[name], parameters)
- @response = request.get(url)
- end
-
-end
@@ -137,10 +137,6 @@ def to_hash
}
end
- def validate!
- raise InvalidParameters, "Parameters requires that at least the uid and the format are set" if uid.nil? || format.nil?
- end
-
private
def to_sorted_array
@@ -52,12 +52,12 @@ def url_to_parameters(path, query_string)
end
def parameters_to_url(parameters)
- parameters.validate!
query_string = [:processing_method, :processing_options, :encoding].map do |attribute|
build_query(MAPPINGS[attribute] => parameters[attribute]) unless parameters[attribute].blank?
end.compact.join('&')
sha_string = "&#{MAPPINGS[:sha]}=#{sha_from_parameters(parameters)}" if protect_from_dos_attacks?
- url = "#{path_prefix}/#{escape_except_for_slashes(parameters.uid)}.#{parameters.format}?#{query_string}#{sha_string}"
+ ext = ".#{parameters.format}" if parameters.format
+ url = "#{path_prefix}/#{escape_except_for_slashes(parameters.uid)}#{ext}?#{query_string}#{sha_string}"
url.sub!(/\?$/,'')
url
end
@@ -82,7 +82,8 @@ def extract_processing_options(path, query)
end
def extract_format(path, query)
- path.sub(/^\//,'').split('.').last
+ bits = path.sub(/^\//,'').split('.')
+ bits.last if bits.length > 1
end
def extract_encoding(path, query)
@@ -140,9 +141,7 @@ def escape_except_for_slashes(string)
end
def validate_format!(path)
- if path !~ /^#{path_prefix}/ || path !~ /^.*[^\/].*\..*[^\/].*$/
- raise UnknownUrl, "path '#{path}' not found"
- end
+ raise UnknownUrl, "path '#{path}' not found" unless path =~ %r(^#{path_prefix}/[^.]+)
end
end
View
Binary file not shown.
@@ -60,7 +60,7 @@ def make_request(app, url)
it "should return 404 if the datastore raises data not found" do
@app.url_handler.protect_from_dos_attacks = false
@app.should_receive(:fetch).and_raise(Dragonfly::DataStorage::DataNotFound)
- response = make_request(@app, 'hello.png')
+ response = make_request(@app, '/hello.png')
response.status.should == 404
end
@@ -76,12 +76,12 @@ def make_request(app, url)
end
it "should use the temp object mime-type" do
@temp_object.should_receive(:mime_type).and_return 'my/type'
- response = make_request(@app, 'hello.png')
+ response = make_request(@app, '/hello.png')
response.headers['Content-Type'].should == 'my/type'
end
it "should use the app's fallback mime-type if the temp_object one isn't known" do
@temp_object.should_receive(:mime_type).and_return nil
- response = make_request(@app, 'hello.png')
+ response = make_request(@app, '/hello.png')
response.headers['Content-Type'].should == 'egg/heads'
end
end
@@ -129,31 +129,6 @@ def standard_attributes
end
- describe "validate!" do
- before(:each) do
- @parameters = Dragonfly::Parameters.new(standard_attributes)
- end
- it "should not raise an error when parameters are ok" do
- @parameters.validate!
- end
- it "should raise an error when the uid is not set" do
- @parameters.uid = nil
- lambda{
- @parameters.validate!
- }.should raise_error(Dragonfly::Parameters::InvalidParameters)
- end
- it "should raise an error when the format is not set" do
- @parameters.format = nil
- lambda{
- @parameters.validate!
- }.should raise_error(Dragonfly::Parameters::InvalidParameters)
- end
- it "should not raise an error when other parameters aren't set" do
- parameters = Dragonfly::Parameters.new(:uid => 'asdf', :format => :jpg)
- parameters.validate!
- end
- end
-
describe "shortcuts" do
before(:each) do
@@ -19,11 +19,6 @@
@parameters.uid.should == 'images/some_image'
end
- it "should behave the same if there is no beginning slash" do
- parameters = @url_handler.url_to_parameters('images/some_image.jpg', @query_string)
- parameters.uid.should == 'images/some_image'
- end
-
it "should take into account the path prefix if there is one" do
@url_handler.path_prefix = '/images'
parameters = @url_handler.url_to_parameters('/images/2009/some_image.jpg', @query_string)
@@ -67,10 +62,10 @@
url_handler.url_to_parameters(@path, @query_string)
end
- it "should raise an UnknownUrl error if the path doesn't have an extension" do
- lambda{
- @url_handler.url_to_parameters('hello', @query_string)
- }.should raise_error(Dragonfly::UrlHandler::UnknownUrl)
+ it "should not set the format if the path doesn't have an extension" do
+ parameters = @url_handler.url_to_parameters('/hello', @query_string)
+ parameters.uid.should == 'hello'
+ parameters.format.should be_nil
end
it "should raise an UnknownUrl error if the path doesn't have a uid bit" do
@@ -86,13 +81,13 @@
end
it "should set most of the path as the uid if there is more than one dot" do
- parameters = @url_handler.url_to_parameters('hello.old.bean', @query_string)
+ parameters = @url_handler.url_to_parameters('/hello.old.bean', @query_string)
parameters.uid.should == 'hello.old'
parameters.format.should == 'bean'
end
it "should unescape any url-escaped characters" do
- parameters = @url_handler.url_to_parameters('hello%20bean.jpg', 'm=whats%20up')
+ parameters = @url_handler.url_to_parameters('/hello%20bean.jpg', 'm=whats%20up')
parameters.uid.should == 'hello bean'
parameters.processing_method.should == 'whats up'
end
@@ -121,6 +116,10 @@
@parameters.processing_method = nil
@url_handler.parameters_to_url(@parameters).should match_url('/thisisunique.gif?o[d]=e&o[j]=k&e[x]=y')
end
+ it "should leave out the format if there is none" do
+ @parameters.format = nil
+ @url_handler.parameters_to_url(@parameters).should match_url('/thisisunique?m=b&o[d]=e&o[j]=k&e[x]=y')
+ end
it "should leave out any empty parameters" do
@parameters.processing_options = {}
@url_handler.parameters_to_url(@parameters).should match_url('/thisisunique.gif?m=b&e[x]=y')
@@ -129,10 +128,6 @@
@url_handler.path_prefix = '/images'
@url_handler.parameters_to_url(@parameters).should match_url('/images/thisisunique.gif?m=b&o[d]=e&o[j]=k&e[x]=y')
end
- it "should validate the parameters" do
- @parameters.should_receive(:validate!)
- @url_handler.parameters_to_url(@parameters)
- end
it "should escape any non-url friendly characters except for '/'" do
parameters = Dragonfly::Parameters.new :uid => 'hello/u"u', :processing_method => 'm"m', :format => 'jpg'
@url_handler.parameters_to_url(parameters).should == '/hello/u%22u.jpg?m=m%22m'

0 comments on commit a2cdb40

Please sign in to comment.