dragonfly 0.8.6 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of dragonfly might be problematic. Click here for more details.
- data/{.specopts → .rspec} +0 -1
- data/.yardopts +6 -2
- data/Gemfile +14 -13
- data/History.md +47 -9
- data/README.md +25 -5
- data/Rakefile +37 -79
- data/VERSION +1 -1
- data/dragonfly.gemspec +140 -89
- data/extra_docs/Analysers.md +8 -48
- data/extra_docs/Configuration.md +40 -25
- data/extra_docs/Couch.md +49 -0
- data/extra_docs/DataStorage.md +94 -24
- data/extra_docs/Encoding.md +6 -35
- data/extra_docs/ExampleUseCases.md +113 -0
- data/extra_docs/GeneralUsage.md +7 -23
- data/extra_docs/Generators.md +15 -49
- data/extra_docs/Heroku.md +7 -8
- data/extra_docs/ImageMagick.md +126 -0
- data/extra_docs/MimeTypes.md +3 -3
- data/extra_docs/Models.md +163 -0
- data/extra_docs/Mongo.md +1 -4
- data/extra_docs/Processing.md +7 -60
- data/extra_docs/Rails2.md +3 -1
- data/extra_docs/Rails3.md +2 -10
- data/extra_docs/ServingRemotely.md +83 -0
- data/extra_docs/Sinatra.md +3 -3
- data/extra_docs/URLs.md +60 -33
- data/features/rails_3.0.5.feature +8 -0
- data/features/steps/rails_steps.rb +7 -18
- data/features/support/env.rb +10 -37
- data/features/support/setup.rb +32 -0
- data/fixtures/rails_3.0.5/files/app/models/album.rb +5 -0
- data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
- data/fixtures/{files → rails_3.0.5/files}/app/views/albums/show.html.erb +2 -0
- data/fixtures/{files → rails_3.0.5/files}/config/initializers/dragonfly.rb +0 -0
- data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
- data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
- data/fixtures/{files → rails_3.0.5/files}/features/step_definitions/image_steps.rb +11 -1
- data/fixtures/{files → rails_3.0.5/files}/features/support/paths.rb +2 -0
- data/fixtures/{files → rails_3.0.5/files}/features/text_images.feature +0 -0
- data/fixtures/{rails_3.0.3 → rails_3.0.5}/template.rb +2 -2
- data/irbrc.rb +2 -1
- data/lib/dragonfly.rb +7 -0
- data/lib/dragonfly/active_model_extensions/attachment.rb +134 -46
- data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +144 -0
- data/lib/dragonfly/active_model_extensions/class_methods.rb +62 -9
- data/lib/dragonfly/active_model_extensions/instance_methods.rb +2 -2
- data/lib/dragonfly/active_model_extensions/validations.rb +10 -6
- data/lib/dragonfly/analyser.rb +0 -1
- data/lib/dragonfly/analysis/file_command_analyser.rb +1 -1
- data/lib/dragonfly/analysis/image_magick_analyser.rb +2 -43
- data/lib/dragonfly/app.rb +64 -55
- data/lib/dragonfly/config/heroku.rb +1 -1
- data/lib/dragonfly/config/image_magick.rb +2 -37
- data/lib/dragonfly/config/rails.rb +5 -2
- data/lib/dragonfly/configurable.rb +115 -35
- data/lib/dragonfly/core_ext/object.rb +1 -1
- data/lib/dragonfly/core_ext/string.rb +1 -1
- data/lib/dragonfly/data_storage/couch_data_store.rb +84 -0
- data/lib/dragonfly/data_storage/file_data_store.rb +43 -18
- data/lib/dragonfly/data_storage/mongo_data_store.rb +8 -4
- data/lib/dragonfly/data_storage/s3data_store.rb +82 -38
- data/lib/dragonfly/encoding/image_magick_encoder.rb +2 -53
- data/lib/dragonfly/function_manager.rb +4 -2
- data/lib/dragonfly/generation/image_magick_generator.rb +2 -136
- data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
- data/lib/dragonfly/image_magick/analyser.rb +51 -0
- data/lib/dragonfly/image_magick/config.rb +44 -0
- data/lib/dragonfly/{encoding/r_magick_encoder.rb → image_magick/encoder.rb} +10 -14
- data/lib/dragonfly/image_magick/generator.rb +145 -0
- data/lib/dragonfly/image_magick/processor.rb +104 -0
- data/lib/dragonfly/image_magick/utils.rb +72 -0
- data/lib/dragonfly/image_magick_utils.rb +2 -79
- data/lib/dragonfly/job.rb +152 -90
- data/lib/dragonfly/middleware.rb +5 -19
- data/lib/dragonfly/processing/image_magick_processor.rb +2 -95
- data/lib/dragonfly/rails/images.rb +15 -10
- data/lib/dragonfly/response.rb +26 -12
- data/lib/dragonfly/serializer.rb +1 -4
- data/lib/dragonfly/server.rb +103 -0
- data/lib/dragonfly/temp_object.rb +56 -101
- data/lib/dragonfly/url_mapper.rb +78 -0
- data/spec/dragonfly/active_model_extensions/model_spec.rb +772 -65
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +90 -10
- data/spec/dragonfly/analyser_spec.rb +1 -1
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +5 -14
- data/spec/dragonfly/app_spec.rb +35 -180
- data/spec/dragonfly/configurable_spec.rb +259 -18
- data/spec/dragonfly/core_ext/string_spec.rb +2 -2
- data/spec/dragonfly/core_ext/symbol_spec.rb +1 -1
- data/spec/dragonfly/data_storage/couch_data_store_spec.rb +84 -0
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +149 -22
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +21 -2
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +207 -43
- data/spec/dragonfly/data_storage/{data_store_spec.rb → shared_data_store_examples.rb} +16 -15
- data/spec/dragonfly/function_manager_spec.rb +2 -2
- data/spec/dragonfly/{generation/hash_with_css_style_keys_spec.rb → hash_with_css_style_keys_spec.rb} +2 -2
- data/spec/dragonfly/{analysis/shared_analyser_spec.rb → image_magick/analyser_spec.rb} +19 -6
- data/spec/dragonfly/{encoding/image_magick_encoder_spec.rb → image_magick/encoder_spec.rb} +2 -2
- data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
- data/spec/dragonfly/{processing/shared_processing_spec.rb → image_magick/processor_spec.rb} +55 -6
- data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
- data/spec/dragonfly/job_builder_spec.rb +1 -1
- data/spec/dragonfly/job_definitions_spec.rb +1 -1
- data/spec/dragonfly/job_endpoint_spec.rb +26 -3
- data/spec/dragonfly/job_spec.rb +426 -208
- data/spec/dragonfly/loggable_spec.rb +2 -2
- data/spec/dragonfly/middleware_spec.rb +5 -26
- data/spec/dragonfly/routed_endpoint_spec.rb +1 -1
- data/spec/dragonfly/serializer_spec.rb +1 -14
- data/spec/dragonfly/server_spec.rb +261 -0
- data/spec/dragonfly/simple_cache_spec.rb +1 -1
- data/spec/dragonfly/temp_object_spec.rb +84 -130
- data/spec/dragonfly/url_mapper_spec.rb +130 -0
- data/spec/functional/deprecations_spec.rb +51 -0
- data/spec/functional/image_magick_app_spec.rb +27 -0
- data/spec/functional/model_urls_spec.rb +85 -0
- data/spec/functional/remote_on_the_fly_spec.rb +51 -0
- data/spec/functional/to_response_spec.rb +31 -0
- data/spec/spec_helper.rb +12 -22
- data/spec/{argument_matchers.rb → support/argument_matchers.rb} +0 -0
- data/spec/{image_matchers.rb → support/image_matchers.rb} +4 -4
- data/spec/support/simple_matchers.rb +53 -0
- data/yard/handlers/configurable_attr_handler.rb +2 -2
- data/yard/templates/default/fulldoc/html/css/common.css +12 -10
- data/yard/templates/default/layout/html/layout.erb +6 -0
- metadata +267 -308
- data/Gemfile.rails.2.3.5 +0 -20
- data/features/3.0.3.feature +0 -8
- data/features/rails_2.3.5.feature +0 -7
- data/fixtures/files/app/models/album.rb +0 -3
- data/fixtures/files/app/views/albums/new.html.erb +0 -4
- data/fixtures/files/features/manage_album_images.feature +0 -12
- data/fixtures/rails_2.3.5/template.rb +0 -10
- data/lib/dragonfly/analysis/r_magick_analyser.rb +0 -63
- data/lib/dragonfly/config/r_magick.rb +0 -46
- data/lib/dragonfly/generation/hash_with_css_style_keys.rb +0 -23
- data/lib/dragonfly/generation/r_magick_generator.rb +0 -155
- data/lib/dragonfly/processing/r_magick_processor.rb +0 -126
- data/lib/dragonfly/r_magick_utils.rb +0 -48
- data/lib/dragonfly/simple_endpoint.rb +0 -76
- data/spec/dragonfly/active_model_extensions/active_model_setup.rb +0 -97
- data/spec/dragonfly/active_model_extensions/active_record_setup.rb +0 -85
- data/spec/dragonfly/analysis/image_magick_analyser_spec.rb +0 -15
- data/spec/dragonfly/analysis/r_magick_analyser_spec.rb +0 -31
- data/spec/dragonfly/config/r_magick_spec.rb +0 -29
- data/spec/dragonfly/encoding/r_magick_encoder_spec.rb +0 -41
- data/spec/dragonfly/generation/image_magick_generator_spec.rb +0 -12
- data/spec/dragonfly/generation/r_magick_generator_spec.rb +0 -28
- data/spec/dragonfly/generation/shared_generator_spec.rb +0 -91
- data/spec/dragonfly/image_magick_utils_spec.rb +0 -16
- data/spec/dragonfly/processing/image_magick_processor_spec.rb +0 -29
- data/spec/dragonfly/processing/r_magick_processor_spec.rb +0 -30
- data/spec/dragonfly/simple_endpoint_spec.rb +0 -97
- data/spec/simple_matchers.rb +0 -44
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
class Testoast
|
4
4
|
include Dragonfly::Loggable
|
@@ -10,7 +10,7 @@ describe Dragonfly::Loggable do
|
|
10
10
|
@object = Testoast.new
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
shared_examples_for "common" do
|
14
14
|
it "should return a log" do
|
15
15
|
@object.log.should be_a(Logger)
|
16
16
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require 'rack'
|
3
3
|
|
4
4
|
def dummy_rack_app
|
@@ -13,27 +13,21 @@ describe Dragonfly::Middleware do
|
|
13
13
|
|
14
14
|
before(:each) do
|
15
15
|
@stack = Rack::Builder.new do
|
16
|
-
use Dragonfly::Middleware, :images
|
16
|
+
use Dragonfly::Middleware, :images
|
17
17
|
run dummy_rack_app
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
it "should pass through
|
22
|
-
Dragonfly[:images].should_not_receive(:call)
|
23
|
-
response = make_request(@stack, '/hello.png?howare=you')
|
24
|
-
response.status.should == 200
|
25
|
-
response.body.should == 'dummy_rack_app body'
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should pass through if the app returns and X-Cascade: pass" do
|
21
|
+
it "should pass through if the app returns X-Cascade: pass" do
|
29
22
|
Dragonfly[:images].should_receive(:call).and_return(
|
30
23
|
[404, {"Content-Type" => 'text/plain', 'X-Cascade' => 'pass'}, ['Not found']]
|
31
24
|
)
|
32
25
|
response = make_request(@stack, '/media/hello.png?howare=you')
|
33
26
|
response.body.should == 'dummy_rack_app body'
|
27
|
+
response.status.should == 200
|
34
28
|
end
|
35
29
|
|
36
|
-
it "should return a 404 if the app returns a 404
|
30
|
+
it "should return a 404 if the app returns a 404" do
|
37
31
|
Dragonfly[:images].should_receive(:call).and_return(
|
38
32
|
[404, {"Content-Type" => 'text/plain'}, ['Not found']]
|
39
33
|
)
|
@@ -41,21 +35,6 @@ describe Dragonfly::Middleware do
|
|
41
35
|
response.status.should == 404
|
42
36
|
end
|
43
37
|
|
44
|
-
%w(0.1 0.9 0.10 1.0 1.0.0 1.0.1).each do |version|
|
45
|
-
it "should pass through if the rack version is #{version} (i.e. no X-Cascade: pass) and the app returns 404" do
|
46
|
-
Rack.should_receive(:version).and_return(version)
|
47
|
-
Dragonfly[:images].should_receive(:call).and_return(
|
48
|
-
[404, {"Content-Type" => 'text/plain'}, ['Not found']]
|
49
|
-
)
|
50
|
-
response = make_request(@stack, '/media/hello.png?howare=you')
|
51
|
-
response.status.should == 200
|
52
|
-
response.body.should == 'dummy_rack_app body'
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
%w(1.1 1.1.1 2.9).each do |version|
|
57
|
-
end
|
58
|
-
|
59
38
|
it "should return as per the dragonfly app if the app returns a 200" do
|
60
39
|
Dragonfly[:images].should_receive(:call).and_return(
|
61
40
|
[200, {"Content-Type" => 'text/plain'}, ['ABCD']]
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require
|
2
|
+
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Dragonfly::Serializer do
|
5
5
|
|
@@ -56,19 +56,6 @@ describe Dragonfly::Serializer do
|
|
56
56
|
marshal_decode('ahasdkjfhasdkfjh')
|
57
57
|
}.should raise_error(Dragonfly::Serializer::BadString)
|
58
58
|
end
|
59
|
-
describe "potentially harmful strings" do
|
60
|
-
['_', 'hello', 'h2', '__send__', 'F'].each do |variable_name|
|
61
|
-
it "should raise an error if the string passed in is potentially harmful (e.g. contains instance variable #{variable_name})" do
|
62
|
-
class C; end
|
63
|
-
c = C.new
|
64
|
-
c.instance_eval{ instance_variable_set("@#{variable_name}", 1) }
|
65
|
-
string = Dragonfly::Serializer.b64_encode(Marshal.dump(c))
|
66
|
-
lambda{
|
67
|
-
marshal_decode(string)
|
68
|
-
}.should raise_error(Dragonfly::Serializer::MaliciousString)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
59
|
end
|
73
60
|
|
74
61
|
end
|
@@ -0,0 +1,261 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack/mock'
|
3
|
+
require 'rack/cache'
|
4
|
+
|
5
|
+
def request(app, path)
|
6
|
+
Rack::MockRequest.new(app).get(path)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Dragonfly::Server do
|
10
|
+
|
11
|
+
describe "responses" do
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
@app = test_app
|
15
|
+
@uid = @app.store('HELLO THERE')
|
16
|
+
@server = Dragonfly::Server.new(@app)
|
17
|
+
@server.url_format = '/media/:job'
|
18
|
+
@job = @app.fetch(@uid)
|
19
|
+
end
|
20
|
+
|
21
|
+
after(:each) do
|
22
|
+
@app.destroy(@uid)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "successful urls" do
|
26
|
+
before(:each) do
|
27
|
+
@server.url_format = '/media/:job/:name.:format'
|
28
|
+
end
|
29
|
+
|
30
|
+
[
|
31
|
+
'',
|
32
|
+
'/name',
|
33
|
+
'/name.ext'
|
34
|
+
].each do |suffix|
|
35
|
+
|
36
|
+
it "should return successfully when given the url with suffix #{suffix.inspect}" do
|
37
|
+
url = "/media/#{@job.serialize}#{suffix}"
|
38
|
+
response = request(@server, url)
|
39
|
+
response.status.should == 200
|
40
|
+
response.body.should == 'HELLO THERE'
|
41
|
+
response.content_type.should == 'application/octet-stream'
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should return successfully with the correct sha given and protection on" do
|
47
|
+
@server.protect_from_dos_attacks = true
|
48
|
+
url = "/media/#{@job.serialize}?sha=#{@job.sha}"
|
49
|
+
response = request(@server, url)
|
50
|
+
response.status.should == 200
|
51
|
+
response.body.should == 'HELLO THERE'
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
it "should work ok with + symbols" do
|
56
|
+
@app.processor.add(:thumb){|t, geometry| "eggs" }
|
57
|
+
@app.datastore.should_receive(:retrieve).with('2011/04/20/20_55_04_114_female_1.jpg').and_return "EGGS"
|
58
|
+
response = request(@server, '/media/BAhbB1sHOgZmSSIpMjAxMS8wNC8yMC8yMF81NV8wNF8xMTRfZmVtYWxlXzEuanBnBjoGRVRbCDoGcDoKdGh1bWJJIgwxMDB4NzU+BjsGVA')
|
59
|
+
response.status.should == 200
|
60
|
+
response.body.should == 'eggs'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should return successfully even if the job is in the query string" do
|
65
|
+
@server.url_format = '/'
|
66
|
+
url = "/?job=#{@job.serialize}"
|
67
|
+
response = request(@server, url)
|
68
|
+
response.status.should == 200
|
69
|
+
response.body.should == 'HELLO THERE'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should return a 400 if no sha given but protection on" do
|
73
|
+
@server.protect_from_dos_attacks = true
|
74
|
+
url = "/media/#{@job.serialize}"
|
75
|
+
response = request(@server, url)
|
76
|
+
response.status.should == 400
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return a 400 if wrong sha given and protection on" do
|
80
|
+
@server.protect_from_dos_attacks = true
|
81
|
+
url = "/media/#{@job.serialize}?sha=asdfs"
|
82
|
+
response = request(@server, url)
|
83
|
+
response.status.should == 400
|
84
|
+
end
|
85
|
+
|
86
|
+
['/media', '/media/'].each do |url|
|
87
|
+
it "should return a 404 when no job given, e.g. #{url.inspect}" do
|
88
|
+
response = request(@server, url)
|
89
|
+
response.status.should == 404
|
90
|
+
response.body.should == 'Not found'
|
91
|
+
response.content_type.should == 'text/plain'
|
92
|
+
response.headers['X-Cascade'].should == 'pass'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should return a 404 when the url matches but doesn't correspond to a job" do
|
97
|
+
response = request(@server, '/media/sadhfasdfdsfsdf')
|
98
|
+
response.status.should == 404
|
99
|
+
response.body.should == 'Not found'
|
100
|
+
response.content_type.should == 'text/plain'
|
101
|
+
response.headers['X-Cascade'].should be_nil
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should return a 404 when the url isn't known at all" do
|
105
|
+
response = request(@server, '/jfasd/dsfa')
|
106
|
+
response.status.should == 404
|
107
|
+
response.body.should == 'Not found'
|
108
|
+
response.content_type.should == 'text/plain'
|
109
|
+
response.headers['X-Cascade'].should == 'pass'
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should return a 404 when the url is a well-encoded but bad array" do
|
113
|
+
url = "/media/#{Dragonfly::Serializer.marshal_encode([[:egg, {:some => 'args'}]])}"
|
114
|
+
response = request(@server, url)
|
115
|
+
response.status.should == 404
|
116
|
+
response.body.should == 'Not found'
|
117
|
+
response.content_type.should == 'text/plain'
|
118
|
+
response.headers['X-Cascade'].should be_nil
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should return a cacheable response" do
|
122
|
+
url = "/media/#{@job.serialize}"
|
123
|
+
cache = Rack::Cache.new(@server, :entitystore => 'heap:/')
|
124
|
+
response = request(cache, url)
|
125
|
+
response.status.should == 200
|
126
|
+
response.headers['X-Rack-Cache'].should == "miss, store"
|
127
|
+
response = request(cache, url)
|
128
|
+
response.status.should == 200
|
129
|
+
response.headers['X-Rack-Cache'].should == "fresh"
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "dragonfly response" do
|
135
|
+
before(:each) do
|
136
|
+
@app = test_app
|
137
|
+
@server = Dragonfly::Server.new(@app)
|
138
|
+
@server.url_format = '/media/:job'
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should return a simple text response" do
|
142
|
+
request(@server, '/dragonfly').should be_a_text_response
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should be configurable" do
|
146
|
+
@server.dragonfly_url = '/hello'
|
147
|
+
request(@server, '/hello').should be_a_text_response
|
148
|
+
request(@server, '/dragonfly').status.should == 404
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should be possible to turn it off" do
|
152
|
+
@server.dragonfly_url = nil
|
153
|
+
request(@server, '/').status.should == 404
|
154
|
+
request(@server, '/dragonfly').status.should == 404
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "urls" do
|
159
|
+
|
160
|
+
before(:each) do
|
161
|
+
@app = test_app
|
162
|
+
@server = Dragonfly::Server.new(@app)
|
163
|
+
@server.url_format = '/media/:job/:basename.:format'
|
164
|
+
@job = @app.fetch('some_uid')
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should generate the correct url when no basename/format" do
|
168
|
+
@server.url_for(@job).should == "/media/#{@job.serialize}"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should generate the correct url when there is a basename and no format" do
|
172
|
+
@server.url_for(@job, :basename => 'hello').should == "/media/#{@job.serialize}/hello"
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should generate the correct url when there is a basename and different format" do
|
176
|
+
@server.url_for(@job, :basename => 'hello', :format => 'gif').should == "/media/#{@job.serialize}/hello.gif"
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should add extra params to the url query string" do
|
180
|
+
@server.url_for(@job, :a => 'thing', :b => 'nuther').should == "/media/#{@job.serialize}?a=thing&b=nuther"
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should add the host to the url if configured" do
|
184
|
+
@server.url_host = 'http://some.server:4000'
|
185
|
+
@server.url_for(@job).should == "http://some.server:4000/media/#{@job.serialize}"
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should add the host to the url if passed in" do
|
189
|
+
@server.url_for(@job, :host => 'https://bungle.com').should == "https://bungle.com/media/#{@job.serialize}"
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should favour the passed in host" do
|
193
|
+
@server.url_host = 'http://some.server:4000'
|
194
|
+
@server.url_for(@job, :host => 'https://smeedy').should == "https://smeedy/media/#{@job.serialize}"
|
195
|
+
end
|
196
|
+
|
197
|
+
describe "Denial of Service protection" do
|
198
|
+
before(:each) do
|
199
|
+
@app = test_app
|
200
|
+
@server = Dragonfly::Server.new(@app)
|
201
|
+
@server.protect_from_dos_attacks = true
|
202
|
+
@job = @app.fetch('some_uid')
|
203
|
+
end
|
204
|
+
it "should generate the correct url" do
|
205
|
+
@server.url_for(@job).should == "/#{@job.serialize}?sha=#{@job.sha}"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
describe "before_serve callback" do
|
212
|
+
|
213
|
+
before(:each) do
|
214
|
+
@app = test_app
|
215
|
+
@app.generator.add(:test){ "TEST" }
|
216
|
+
@server = Dragonfly::Server.new(@app)
|
217
|
+
@job = @app.generate(:test)
|
218
|
+
end
|
219
|
+
|
220
|
+
context "with no stop in the callback" do
|
221
|
+
before(:each) do
|
222
|
+
@x = x = ""
|
223
|
+
@server.before_serve do |job, env|
|
224
|
+
x << job.data
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should be called before serving" do
|
229
|
+
response = request(@server, "/#{@job.serialize}")
|
230
|
+
response.body.should == 'TEST'
|
231
|
+
@x.should == 'TEST'
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should not be called before serving a 404 page" do
|
235
|
+
response = request(@server, "blah")
|
236
|
+
response.status.should == 404
|
237
|
+
@x.should == ""
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
context "with a throw :halt in the callback" do
|
242
|
+
before(:each) do
|
243
|
+
@server.before_serve do |job, env|
|
244
|
+
throw :halt, [200, {}, ['hello']]
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'return the specified response instead of job.result' do
|
249
|
+
response = request(@server, "/#{@job.serialize}")
|
250
|
+
response.body.should == 'hello'
|
251
|
+
end
|
252
|
+
|
253
|
+
it "should not apply the job if not asked to" do
|
254
|
+
@app.generator.should_not_receive(:generate)
|
255
|
+
response = request(@server, "/#{@job.serialize}")
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Dragonfly::TempObject do
|
4
4
|
|
5
5
|
####### Helper Methods #######
|
6
6
|
|
7
7
|
def sample_path(filename)
|
8
|
-
File.
|
8
|
+
File.join(SAMPLES_DIR, filename)
|
9
9
|
end
|
10
10
|
|
11
11
|
def new_tempfile(data='HELLO')
|
@@ -15,16 +15,22 @@ describe Dragonfly::TempObject do
|
|
15
15
|
tempfile
|
16
16
|
end
|
17
17
|
|
18
|
-
def new_file(data='HELLO')
|
19
|
-
File.open(
|
18
|
+
def new_file(data='HELLO', path="/tmp/test_file")
|
19
|
+
File.open(path, 'w') do |f|
|
20
20
|
f.write(data)
|
21
21
|
end
|
22
|
-
File.new(
|
22
|
+
File.new(path)
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
25
|
+
def new_pathname(data='HELLO', path="/tmp/test_file")
|
26
|
+
File.open(path, 'w') do |f|
|
27
|
+
f.write(data)
|
28
|
+
end
|
29
|
+
Pathname.new(path)
|
30
|
+
end
|
31
|
+
|
32
|
+
def new_temp_object(data, klass=Dragonfly::TempObject)
|
33
|
+
klass.new(initialization_object(data))
|
28
34
|
end
|
29
35
|
|
30
36
|
def initialization_object(data)
|
@@ -48,7 +54,7 @@ describe Dragonfly::TempObject do
|
|
48
54
|
}.should raise_error(ArgumentError)
|
49
55
|
end
|
50
56
|
|
51
|
-
|
57
|
+
shared_examples_for "common behaviour" do
|
52
58
|
|
53
59
|
describe "simple initialization" do
|
54
60
|
|
@@ -97,8 +103,8 @@ describe Dragonfly::TempObject do
|
|
97
103
|
end
|
98
104
|
|
99
105
|
describe "path" do
|
100
|
-
it "should return
|
101
|
-
@temp_object.path.should
|
106
|
+
it "should return an absolute file path" do
|
107
|
+
@temp_object.path.should =~ %r{^/\w+}
|
102
108
|
end
|
103
109
|
end
|
104
110
|
|
@@ -133,26 +139,6 @@ describe Dragonfly::TempObject do
|
|
133
139
|
|
134
140
|
end
|
135
141
|
|
136
|
-
describe "initializing attributes too" do
|
137
|
-
it "should set the name" do
|
138
|
-
temp_object = Dragonfly::TempObject.new(initialization_object('HELLO'), :name => 'monkey.egg')
|
139
|
-
temp_object.name.should == 'monkey.egg'
|
140
|
-
end
|
141
|
-
it "should set the meta" do
|
142
|
-
temp_object = Dragonfly::TempObject.new(initialization_object('HELLO'), :meta => {:dr => 'doolittle'})
|
143
|
-
temp_object.meta.should == {:dr => 'doolittle'}
|
144
|
-
end
|
145
|
-
it "should set the format" do
|
146
|
-
temp_object = Dragonfly::TempObject.new(initialization_object('HELLO'), :format => :jpg)
|
147
|
-
temp_object.format.should == :jpg
|
148
|
-
end
|
149
|
-
it "should raise an error if an invalid option is given" do
|
150
|
-
lambda {
|
151
|
-
Dragonfly::TempObject.new(initialization_object('HELLO'), :doobie => 'doo')
|
152
|
-
}.should raise_error(ArgumentError)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
142
|
describe "each" do
|
157
143
|
it "should yield 8192 bytes each time" do
|
158
144
|
temp_object = new_temp_object(File.read(sample_path('round.gif')))
|
@@ -164,7 +150,7 @@ describe Dragonfly::TempObject do
|
|
164
150
|
end
|
165
151
|
it "should yield the number of bytes specified in the class configuration" do
|
166
152
|
klass = Class.new(Dragonfly::TempObject)
|
167
|
-
temp_object = new_temp_object(File.read(sample_path('round.gif')),
|
153
|
+
temp_object = new_temp_object(File.read(sample_path('round.gif')), klass)
|
168
154
|
klass.block_size = 3001
|
169
155
|
parts = get_parts(temp_object)
|
170
156
|
parts[0...-1].each do |part|
|
@@ -204,6 +190,11 @@ describe Dragonfly::TempObject do
|
|
204
190
|
temp_object.should_not_receive(:data)
|
205
191
|
temp_object.each{}
|
206
192
|
end
|
193
|
+
|
194
|
+
it "should return the tempfile's path" do
|
195
|
+
temp_object = new_temp_object('HELLO')
|
196
|
+
temp_object.path.should == temp_object.tempfile.path
|
197
|
+
end
|
207
198
|
end
|
208
199
|
|
209
200
|
describe "initializing from a file" do
|
@@ -219,133 +210,96 @@ describe Dragonfly::TempObject do
|
|
219
210
|
temp_object.should_not_receive(:data)
|
220
211
|
temp_object.each{}
|
221
212
|
end
|
213
|
+
|
214
|
+
it "should return the file's path" do
|
215
|
+
file = new_file('HELLO')
|
216
|
+
temp_object = Dragonfly::TempObject.new(file)
|
217
|
+
temp_object.path.should == file.path
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should return an absolute path even if the file wasn't instantiated like that" do
|
221
|
+
file = new_file('HELLO', 'testfile')
|
222
|
+
temp_object = Dragonfly::TempObject.new(file)
|
223
|
+
temp_object.path.should =~ %r{^/\w.*testfile}
|
224
|
+
file.close
|
225
|
+
FileUtils.rm(file.path)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
describe "initializing from a pathname" do
|
230
|
+
|
231
|
+
def initialization_object(data)
|
232
|
+
new_pathname(data)
|
233
|
+
end
|
234
|
+
|
235
|
+
it_should_behave_like "common behaviour"
|
236
|
+
|
237
|
+
it "should not create a data string when calling each" do
|
238
|
+
temp_object = new_temp_object('HELLO')
|
239
|
+
temp_object.should_not_receive(:data)
|
240
|
+
temp_object.each{}
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should return the file's path" do
|
244
|
+
pathname = new_pathname('HELLO')
|
245
|
+
temp_object = Dragonfly::TempObject.new(pathname)
|
246
|
+
temp_object.path.should == pathname.to_s
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should return an absolute path even if the pathname is relative" do
|
250
|
+
pathname = new_pathname('HELLO', 'testfile')
|
251
|
+
temp_object = Dragonfly::TempObject.new(pathname)
|
252
|
+
temp_object.path.should =~ %r{^/\w.*testfile}
|
253
|
+
pathname.delete
|
254
|
+
end
|
222
255
|
end
|
223
256
|
|
224
257
|
describe "initializing from another temp object" do
|
258
|
+
|
259
|
+
def initialization_object(data)
|
260
|
+
Dragonfly::TempObject.new(data)
|
261
|
+
end
|
262
|
+
|
225
263
|
before(:each) do
|
226
264
|
@temp_object1 = Dragonfly::TempObject.new(new_tempfile('hello'))
|
227
265
|
@temp_object2 = Dragonfly::TempObject.new(@temp_object1)
|
228
266
|
end
|
267
|
+
|
268
|
+
it_should_behave_like "common behaviour"
|
269
|
+
|
229
270
|
it "should not be the same object" do
|
230
271
|
@temp_object1.should_not == @temp_object2
|
231
272
|
end
|
232
273
|
it "should have the same data" do
|
233
274
|
@temp_object1.data.should == @temp_object2.data
|
234
275
|
end
|
235
|
-
it "should have
|
236
|
-
@temp_object1.path.
|
276
|
+
it "should have the same file path" do
|
277
|
+
@temp_object1.path.should == @temp_object2.path
|
237
278
|
end
|
238
279
|
end
|
239
280
|
|
240
|
-
describe "
|
281
|
+
describe "original_filename" do
|
241
282
|
before(:each) do
|
242
283
|
@obj = new_tempfile
|
243
284
|
end
|
244
|
-
it "should set the
|
285
|
+
it "should set the original_filename if the initial object responds to 'original filename'" do
|
245
286
|
def @obj.original_filename
|
246
287
|
'jimmy.page'
|
247
288
|
end
|
248
|
-
Dragonfly::TempObject.new(@obj).
|
289
|
+
Dragonfly::TempObject.new(@obj).original_filename.should == 'jimmy.page'
|
249
290
|
end
|
250
291
|
it "should not set the name if the initial object doesn't respond to 'original filename'" do
|
251
|
-
Dragonfly::TempObject.new(@obj).
|
292
|
+
Dragonfly::TempObject.new(@obj).original_filename.should be_nil
|
252
293
|
end
|
253
294
|
it "should set the name if the initial object is a file object" do
|
254
295
|
file = File.new(SAMPLES_DIR + '/round.gif')
|
255
296
|
temp_object = Dragonfly::TempObject.new(file)
|
256
|
-
temp_object.
|
257
|
-
end
|
258
|
-
it "should still be nil if set to empty string on initialize" do
|
259
|
-
temp_object = Dragonfly::TempObject.new('sdf', :name => '')
|
260
|
-
temp_object.name.should be_nil
|
261
|
-
end
|
262
|
-
it "should allow setting" do
|
263
|
-
temp_object = Dragonfly::TempObject.new('sdf')
|
264
|
-
temp_object.name = "jonny.briggs"
|
265
|
-
temp_object.name.should == 'jonny.briggs'
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
describe "ext" do
|
270
|
-
it "should use the correct extension from name" do
|
271
|
-
temp_object = Dragonfly::TempObject.new('asfsadf', :name => 'hello.there.mate')
|
272
|
-
temp_object.ext.should == 'mate'
|
273
|
-
end
|
274
|
-
it "should be nil if name has none" do
|
275
|
-
temp_object = Dragonfly::TempObject.new('asfsadf', :name => 'hello')
|
276
|
-
temp_object.ext.should be_nil
|
277
|
-
end
|
278
|
-
it "should be nil if name is nil" do
|
279
|
-
temp_object = Dragonfly::TempObject.new('asfsadf')
|
280
|
-
temp_object.ext.should be_nil
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
describe "basename" do
|
285
|
-
it "should use the correct basename from name" do
|
286
|
-
temp_object = Dragonfly::TempObject.new('A', :name => 'hello.there.mate')
|
287
|
-
temp_object.basename.should == 'hello.there'
|
288
|
-
end
|
289
|
-
it "should be the name if it has no ext" do
|
290
|
-
temp_object = Dragonfly::TempObject.new('A', :name => 'hello')
|
291
|
-
temp_object.basename.should == 'hello'
|
292
|
-
end
|
293
|
-
it "should be nil if name is nil" do
|
294
|
-
temp_object = Dragonfly::TempObject.new('A', :name => nil)
|
295
|
-
temp_object.basename.should be_nil
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
describe "meta" do
|
300
|
-
before(:each) do
|
301
|
-
@temp_object = Dragonfly::TempObject.new('get outta here!')
|
302
|
-
end
|
303
|
-
it "should return an empty hash if not set" do
|
304
|
-
@temp_object.meta.should == {}
|
305
|
-
end
|
306
|
-
it "should allow setting" do
|
307
|
-
@temp_object.meta = {:teeth => 'many'}
|
308
|
-
@temp_object.meta.should == {:teeth => 'many'}
|
309
|
-
end
|
310
|
-
end
|
311
|
-
|
312
|
-
describe "format" do
|
313
|
-
it "should return nil if not set" do
|
314
|
-
temp_object = Dragonfly::TempObject.new('wassin my belly??!')
|
315
|
-
temp_object.format.should be_nil
|
316
|
-
end
|
317
|
-
it "should allow setting on initialize" do
|
318
|
-
temp_object = Dragonfly::TempObject.new('wassin my belly??!', :format => :jpg)
|
319
|
-
temp_object.format.should == :jpg
|
320
|
-
end
|
321
|
-
it "should allow setting" do
|
322
|
-
temp_object = Dragonfly::TempObject.new('jo*ida pero contenta')
|
323
|
-
temp_object.format = :tiff
|
324
|
-
temp_object.format.should == :tiff
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
describe "extract_attributes_from" do
|
329
|
-
before(:each) do
|
330
|
-
@temp_object = Dragonfly::TempObject.new("ne'er gonna give you up",
|
331
|
-
:meta => {:a => 4},
|
332
|
-
:name => 'fred.txt',
|
333
|
-
:format => :txt
|
334
|
-
)
|
335
|
-
@attributes = {:meta => {:b => 5}, :ogle => 'bogle', :format => :dungbats}
|
336
|
-
@temp_object.extract_attributes_from(@attributes)
|
337
|
-
end
|
338
|
-
it "should overwrite its own attributes if specified" do
|
339
|
-
@temp_object.format.should == :dungbats
|
340
|
-
end
|
341
|
-
it "should merge its own meta if specified" do
|
342
|
-
@temp_object.meta.should == {:a => 4, :b => 5}
|
343
|
-
end
|
344
|
-
it "should leave non-specified attributes untouched" do
|
345
|
-
@temp_object.name.should == 'fred.txt'
|
297
|
+
temp_object.original_filename.should == 'round.gif'
|
346
298
|
end
|
347
|
-
it "should
|
348
|
-
|
299
|
+
it "should set the name if the initial object is a pathname" do
|
300
|
+
pathname = Pathname.new(SAMPLES_DIR + '/round.gif')
|
301
|
+
temp_object = Dragonfly::TempObject.new(pathname)
|
302
|
+
temp_object.original_filename.should == 'round.gif'
|
349
303
|
end
|
350
304
|
end
|
351
305
|
|