oahu-dragonfly 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. data/.rspec +1 -0
  2. data/.yardopts +24 -0
  3. data/Gemfile +30 -0
  4. data/History.md +323 -0
  5. data/LICENSE +20 -0
  6. data/README.md +88 -0
  7. data/Rakefile +50 -0
  8. data/VERSION +1 -0
  9. data/config.ru +14 -0
  10. data/docs.watchr +1 -0
  11. data/dragonfly.gemspec +297 -0
  12. data/extra_docs/Analysers.md +66 -0
  13. data/extra_docs/Caching.md +23 -0
  14. data/extra_docs/Configuration.md +124 -0
  15. data/extra_docs/Couch.md +49 -0
  16. data/extra_docs/DataStorage.md +153 -0
  17. data/extra_docs/Encoding.md +67 -0
  18. data/extra_docs/GeneralUsage.md +121 -0
  19. data/extra_docs/Generators.md +60 -0
  20. data/extra_docs/Heroku.md +50 -0
  21. data/extra_docs/ImageMagick.md +125 -0
  22. data/extra_docs/Index.md +33 -0
  23. data/extra_docs/MimeTypes.md +40 -0
  24. data/extra_docs/Models.md +272 -0
  25. data/extra_docs/Mongo.md +45 -0
  26. data/extra_docs/Processing.md +77 -0
  27. data/extra_docs/Rack.md +52 -0
  28. data/extra_docs/Rails2.md +57 -0
  29. data/extra_docs/Rails3.md +62 -0
  30. data/extra_docs/Sinatra.md +25 -0
  31. data/extra_docs/URLs.md +169 -0
  32. data/features/images.feature +47 -0
  33. data/features/no_processing.feature +14 -0
  34. data/features/rails_3.0.5.feature +8 -0
  35. data/features/steps/common_steps.rb +8 -0
  36. data/features/steps/dragonfly_steps.rb +66 -0
  37. data/features/steps/rails_steps.rb +28 -0
  38. data/features/support/env.rb +13 -0
  39. data/features/support/setup.rb +32 -0
  40. data/fixtures/rails_3.0.5/files/app/models/album.rb +7 -0
  41. data/fixtures/rails_3.0.5/files/app/views/albums/new.html.erb +7 -0
  42. data/fixtures/rails_3.0.5/files/app/views/albums/show.html.erb +6 -0
  43. data/fixtures/rails_3.0.5/files/config/initializers/dragonfly.rb +4 -0
  44. data/fixtures/rails_3.0.5/files/features/manage_album_images.feature +38 -0
  45. data/fixtures/rails_3.0.5/files/features/step_definitions/helper_steps.rb +7 -0
  46. data/fixtures/rails_3.0.5/files/features/step_definitions/image_steps.rb +25 -0
  47. data/fixtures/rails_3.0.5/files/features/support/paths.rb +17 -0
  48. data/fixtures/rails_3.0.5/files/features/text_images.feature +7 -0
  49. data/fixtures/rails_3.0.5/template.rb +20 -0
  50. data/irbrc.rb +18 -0
  51. data/lib/dragonfly.rb +55 -0
  52. data/lib/dragonfly/active_model_extensions.rb +13 -0
  53. data/lib/dragonfly/active_model_extensions/attachment.rb +250 -0
  54. data/lib/dragonfly/active_model_extensions/attachment_class_methods.rb +148 -0
  55. data/lib/dragonfly/active_model_extensions/class_methods.rb +95 -0
  56. data/lib/dragonfly/active_model_extensions/instance_methods.rb +28 -0
  57. data/lib/dragonfly/active_model_extensions/validations.rb +41 -0
  58. data/lib/dragonfly/analyser.rb +58 -0
  59. data/lib/dragonfly/analysis/file_command_analyser.rb +32 -0
  60. data/lib/dragonfly/analysis/image_magick_analyser.rb +6 -0
  61. data/lib/dragonfly/app.rb +172 -0
  62. data/lib/dragonfly/config/heroku.rb +19 -0
  63. data/lib/dragonfly/config/image_magick.rb +6 -0
  64. data/lib/dragonfly/config/rails.rb +20 -0
  65. data/lib/dragonfly/configurable.rb +207 -0
  66. data/lib/dragonfly/core_ext/array.rb +7 -0
  67. data/lib/dragonfly/core_ext/hash.rb +7 -0
  68. data/lib/dragonfly/core_ext/object.rb +12 -0
  69. data/lib/dragonfly/core_ext/string.rb +9 -0
  70. data/lib/dragonfly/core_ext/symbol.rb +9 -0
  71. data/lib/dragonfly/data_storage.rb +9 -0
  72. data/lib/dragonfly/data_storage/couch_data_store.rb +64 -0
  73. data/lib/dragonfly/data_storage/file_data_store.rb +141 -0
  74. data/lib/dragonfly/data_storage/mongo_data_store.rb +86 -0
  75. data/lib/dragonfly/data_storage/s3data_store.rb +145 -0
  76. data/lib/dragonfly/encoder.rb +13 -0
  77. data/lib/dragonfly/encoding/image_magick_encoder.rb +6 -0
  78. data/lib/dragonfly/function_manager.rb +71 -0
  79. data/lib/dragonfly/generation/image_magick_generator.rb +6 -0
  80. data/lib/dragonfly/generator.rb +9 -0
  81. data/lib/dragonfly/hash_with_css_style_keys.rb +21 -0
  82. data/lib/dragonfly/image_magick/analyser.rb +51 -0
  83. data/lib/dragonfly/image_magick/config.rb +41 -0
  84. data/lib/dragonfly/image_magick/encoder.rb +57 -0
  85. data/lib/dragonfly/image_magick/generator.rb +145 -0
  86. data/lib/dragonfly/image_magick/processor.rb +99 -0
  87. data/lib/dragonfly/image_magick/utils.rb +72 -0
  88. data/lib/dragonfly/image_magick_utils.rb +4 -0
  89. data/lib/dragonfly/job.rb +451 -0
  90. data/lib/dragonfly/job_builder.rb +39 -0
  91. data/lib/dragonfly/job_definitions.rb +26 -0
  92. data/lib/dragonfly/job_endpoint.rb +15 -0
  93. data/lib/dragonfly/loggable.rb +28 -0
  94. data/lib/dragonfly/middleware.rb +20 -0
  95. data/lib/dragonfly/processing/image_magick_processor.rb +6 -0
  96. data/lib/dragonfly/processor.rb +9 -0
  97. data/lib/dragonfly/rails/images.rb +27 -0
  98. data/lib/dragonfly/response.rb +97 -0
  99. data/lib/dragonfly/routed_endpoint.rb +40 -0
  100. data/lib/dragonfly/serializer.rb +32 -0
  101. data/lib/dragonfly/server.rb +113 -0
  102. data/lib/dragonfly/simple_cache.rb +23 -0
  103. data/lib/dragonfly/temp_object.rb +175 -0
  104. data/lib/dragonfly/url_mapper.rb +78 -0
  105. data/samples/beach.png +0 -0
  106. data/samples/egg.png +0 -0
  107. data/samples/round.gif +0 -0
  108. data/samples/sample.docx +0 -0
  109. data/samples/taj.jpg +0 -0
  110. data/spec/dragonfly/active_model_extensions/model_spec.rb +1426 -0
  111. data/spec/dragonfly/active_model_extensions/spec_helper.rb +91 -0
  112. data/spec/dragonfly/analyser_spec.rb +123 -0
  113. data/spec/dragonfly/analysis/file_command_analyser_spec.rb +48 -0
  114. data/spec/dragonfly/app_spec.rb +135 -0
  115. data/spec/dragonfly/configurable_spec.rb +461 -0
  116. data/spec/dragonfly/core_ext/array_spec.rb +19 -0
  117. data/spec/dragonfly/core_ext/hash_spec.rb +19 -0
  118. data/spec/dragonfly/core_ext/string_spec.rb +17 -0
  119. data/spec/dragonfly/core_ext/symbol_spec.rb +17 -0
  120. data/spec/dragonfly/data_storage/couch_data_store_spec.rb +76 -0
  121. data/spec/dragonfly/data_storage/file_data_store_spec.rb +296 -0
  122. data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +57 -0
  123. data/spec/dragonfly/data_storage/s3_data_store_spec.rb +258 -0
  124. data/spec/dragonfly/data_storage/shared_data_store_examples.rb +77 -0
  125. data/spec/dragonfly/function_manager_spec.rb +154 -0
  126. data/spec/dragonfly/hash_with_css_style_keys_spec.rb +24 -0
  127. data/spec/dragonfly/image_magick/analyser_spec.rb +64 -0
  128. data/spec/dragonfly/image_magick/encoder_spec.rb +41 -0
  129. data/spec/dragonfly/image_magick/generator_spec.rb +172 -0
  130. data/spec/dragonfly/image_magick/processor_spec.rb +233 -0
  131. data/spec/dragonfly/image_magick/utils_spec.rb +18 -0
  132. data/spec/dragonfly/job_builder_spec.rb +37 -0
  133. data/spec/dragonfly/job_definitions_spec.rb +35 -0
  134. data/spec/dragonfly/job_endpoint_spec.rb +173 -0
  135. data/spec/dragonfly/job_spec.rb +1046 -0
  136. data/spec/dragonfly/loggable_spec.rb +80 -0
  137. data/spec/dragonfly/middleware_spec.rb +47 -0
  138. data/spec/dragonfly/routed_endpoint_spec.rb +48 -0
  139. data/spec/dragonfly/serializer_spec.rb +61 -0
  140. data/spec/dragonfly/server_spec.rb +278 -0
  141. data/spec/dragonfly/simple_cache_spec.rb +27 -0
  142. data/spec/dragonfly/temp_object_spec.rb +306 -0
  143. data/spec/dragonfly/url_mapper_spec.rb +126 -0
  144. data/spec/functional/deprecations_spec.rb +51 -0
  145. data/spec/functional/image_magick_app_spec.rb +27 -0
  146. data/spec/functional/model_urls_spec.rb +85 -0
  147. data/spec/functional/remote_on_the_fly_spec.rb +51 -0
  148. data/spec/functional/to_response_spec.rb +31 -0
  149. data/spec/spec_helper.rb +51 -0
  150. data/spec/support/argument_matchers.rb +19 -0
  151. data/spec/support/image_matchers.rb +47 -0
  152. data/spec/support/simple_matchers.rb +53 -0
  153. data/yard/handlers/configurable_attr_handler.rb +38 -0
  154. data/yard/setup.rb +15 -0
  155. data/yard/templates/default/fulldoc/html/css/common.css +107 -0
  156. data/yard/templates/default/layout/html/layout.erb +89 -0
  157. data/yard/templates/default/module/html/configuration_summary.erb +31 -0
  158. data/yard/templates/default/module/setup.rb +17 -0
  159. metadata +544 -0
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ class Testoast
4
+ include Dragonfly::Loggable
5
+ end
6
+
7
+ describe Dragonfly::Loggable do
8
+
9
+ before(:each) do
10
+ @object = Testoast.new
11
+ end
12
+
13
+ shared_examples_for "common" do
14
+ it "should return a log" do
15
+ @object.log.should be_a(Logger)
16
+ end
17
+ it "should cache the log" do
18
+ @object.log.should == @object.log
19
+ end
20
+ end
21
+
22
+ describe "without being set" do
23
+ it "should return the log object as nil" do
24
+ @object.log_object.should be_nil
25
+ end
26
+ it_should_behave_like 'common'
27
+ end
28
+
29
+ describe "when set" do
30
+ before(:each) do
31
+ @log = Logger.new($stdout)
32
+ @object.log = @log
33
+ end
34
+ it "should return the new log" do
35
+ @object.log.should == @log
36
+ end
37
+ it "should return the log object" do
38
+ @object.log_object.should == @log
39
+ end
40
+ it_should_behave_like 'common'
41
+ end
42
+
43
+ describe "when set as a proc" do
44
+ before(:each) do
45
+ @log = Logger.new($stdout)
46
+ @object.log = proc{ @log }
47
+ end
48
+ it "should return the new log" do
49
+ @object.log.should == @log
50
+ end
51
+ it "should return the log object" do
52
+ @object.log_object.should be_a(Proc)
53
+ end
54
+ it "should allow for changing logs" do
55
+ logs = [@log]
56
+ @object.log = proc{ logs[0] }
57
+ @object.log.should == @log
58
+
59
+ new_log = Logger.new($stdout)
60
+ logs[0] = new_log
61
+
62
+ @object.log.should == new_log
63
+ end
64
+ it_should_behave_like 'common'
65
+ end
66
+
67
+ describe "sharing logs" do
68
+ before(:each) do
69
+ @log = Logger.new($stdout)
70
+ @obj1 = Testoast.new
71
+ @obj2 = Testoast.new
72
+ end
73
+ it "should enable sharing logs" do
74
+ @obj1.log = proc{ @log }
75
+ @obj2.use_same_log_as(@obj1)
76
+ @obj2.log.should == @log
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require 'rack'
3
+
4
+ def dummy_rack_app
5
+ lambda{|env| [200, {"Content-Type" => "text/html"}, ["dummy_rack_app body"]] }
6
+ end
7
+
8
+ describe Dragonfly::Middleware do
9
+
10
+ def make_request(app, url)
11
+ Rack::MockRequest.new(app).get(url)
12
+ end
13
+
14
+ before(:each) do
15
+ @stack = Rack::Builder.new do
16
+ use Dragonfly::Middleware, :images
17
+ run dummy_rack_app
18
+ end
19
+ end
20
+
21
+ it "should pass through if the app returns X-Cascade: pass" do
22
+ Dragonfly[:images].should_receive(:call).and_return(
23
+ [404, {"Content-Type" => 'text/plain', 'X-Cascade' => 'pass'}, ['Not found']]
24
+ )
25
+ response = make_request(@stack, '/media/hello.png?howare=you')
26
+ response.body.should == 'dummy_rack_app body'
27
+ response.status.should == 200
28
+ end
29
+
30
+ it "should return a 404 if the app returns a 404" do
31
+ Dragonfly[:images].should_receive(:call).and_return(
32
+ [404, {"Content-Type" => 'text/plain'}, ['Not found']]
33
+ )
34
+ response = make_request(@stack, '/media/hello.png?howare=you')
35
+ response.status.should == 404
36
+ end
37
+
38
+ it "should return as per the dragonfly app if the app returns a 200" do
39
+ Dragonfly[:images].should_receive(:call).and_return(
40
+ [200, {"Content-Type" => 'text/plain'}, ['ABCD']]
41
+ )
42
+ response = make_request(@stack, '/media/hello.png?howare=you')
43
+ response.status.should == 200
44
+ response.body.should == 'ABCD'
45
+ end
46
+
47
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ def response_for(array)
4
+ Rack::MockResponse.new(*array)
5
+ end
6
+
7
+ describe Dragonfly::RoutedEndpoint do
8
+
9
+ def env_for(url, opts={})
10
+ Rack::MockRequest.env_for(url, opts)
11
+ end
12
+
13
+ before(:each) do
14
+ @app = test_app
15
+ @endpoint = Dragonfly::RoutedEndpoint.new(@app) {|params, app|
16
+ app.fetch(params[:uid])
17
+ }
18
+ @app.datastore.stub!(:retrieve).with('some_uid').and_return Dragonfly::TempObject.new('wassup')
19
+ end
20
+
21
+ it "should raise an error when there are no routing parameters" do
22
+ lambda{
23
+ @endpoint.call(env_for('/blah'))
24
+ }.should raise_error(Dragonfly::RoutedEndpoint::NoRoutingParams)
25
+ end
26
+
27
+ {
28
+ 'Rails' => 'action_dispatch.request.path_parameters',
29
+ 'Usher' => 'usher.params',
30
+ 'HTTP Router' => 'router.params',
31
+ 'Rack-Mount' => 'rack.routing_args',
32
+ 'Dragonfly' => 'dragonfly.params'
33
+ }.each do |name, key|
34
+
35
+ it "should work with #{name} routing args" do
36
+ response = response_for @endpoint.call(env_for('/blah', key => {:uid => 'some_uid'}))
37
+ response.body.should == 'wassup'
38
+ end
39
+
40
+ end
41
+
42
+ it "should merge with query parameters" do
43
+ env = Rack::MockRequest.env_for('/big/buns?uid=some_uid', 'dragonfly.params' => {:something => 'else'})
44
+ response = response_for @endpoint.call(env)
45
+ response.body.should == 'wassup'
46
+ end
47
+
48
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Dragonfly::Serializer do
5
+
6
+ include Dragonfly::Serializer
7
+
8
+ [
9
+ 'a',
10
+ 'sdhflasd',
11
+ '/2010/03/01/hello.png',
12
+ '//..',
13
+ 'whats/up.egg.frog',
14
+ '£ñçùí;'
15
+ ].each do |string|
16
+ it "should encode #{string.inspect} properly with no padding/line break" do
17
+ b64_encode(string).should_not =~ /\n|=/
18
+ end
19
+ it "should correctly encode and decode #{string.inspect} to the same string" do
20
+ str = b64_decode(b64_encode(string))
21
+ str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
22
+ str.should == string
23
+ end
24
+ end
25
+
26
+ [
27
+ :hello,
28
+ nil,
29
+ true,
30
+ 4,
31
+ 2.3,
32
+ 'wassup man',
33
+ [3,4,5],
34
+ {:wo => 'there'},
35
+ [{:this => 'should', :work => [3, 5.3, nil, {false => 'egg'}]}, [], true]
36
+ ].each do |object|
37
+ it "should correctly marshal encode #{object.inspect} properly with no padding/line break" do
38
+ encoded = marshal_encode(object)
39
+ # raise encoded.index("\n").inspect
40
+ encoded.should be_a(String)
41
+ encoded.should_not =~ /\n|=/
42
+ end
43
+ it "should correctly marshal encode and decode #{object.inspect} to the same object" do
44
+ marshal_decode(marshal_encode(object)).should == object
45
+ end
46
+ end
47
+
48
+ describe "marshal_decode" do
49
+ it "should raise an error if the string passed in is empty" do
50
+ lambda{
51
+ marshal_decode('')
52
+ }.should raise_error(Dragonfly::Serializer::BadString)
53
+ end
54
+ it "should raise an error if the string passed in is gobbledeegook" do
55
+ lambda{
56
+ marshal_decode('ahasdkjfhasdkfjh')
57
+ }.should raise_error(Dragonfly::Serializer::BadString)
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,278 @@
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
+ end
55
+
56
+ it "should return successfully even if the job is in the query string" do
57
+ @server.url_format = '/'
58
+ url = "/?job=#{@job.serialize}"
59
+ response = request(@server, url)
60
+ response.status.should == 200
61
+ response.body.should == 'HELLO THERE'
62
+ end
63
+
64
+ it "should return a 400 if no sha given but protection on" do
65
+ @server.protect_from_dos_attacks = true
66
+ url = "/media/#{@job.serialize}"
67
+ response = request(@server, url)
68
+ response.status.should == 400
69
+ end
70
+
71
+ it "should return a 400 if wrong sha given and protection on" do
72
+ @server.protect_from_dos_attacks = true
73
+ url = "/media/#{@job.serialize}?sha=asdfs"
74
+ response = request(@server, url)
75
+ response.status.should == 400
76
+ end
77
+
78
+ ['/media', '/media/'].each do |url|
79
+ it "should return a 404 when no job given, e.g. #{url.inspect}" do
80
+ response = request(@server, url)
81
+ response.status.should == 404
82
+ response.body.should == 'Not found'
83
+ response.content_type.should == 'text/plain'
84
+ response.headers['X-Cascade'].should == 'pass'
85
+ end
86
+ end
87
+
88
+ it "should return a 404 when the url matches but doesn't correspond to a job" do
89
+ response = request(@server, '/media/sadhfasdfdsfsdf')
90
+ response.status.should == 404
91
+ response.body.should == 'Not found'
92
+ response.content_type.should == 'text/plain'
93
+ response.headers['X-Cascade'].should be_nil
94
+ end
95
+
96
+ it "should return a 404 when the url isn't known at all" do
97
+ response = request(@server, '/jfasd/dsfa')
98
+ response.status.should == 404
99
+ response.body.should == 'Not found'
100
+ response.content_type.should == 'text/plain'
101
+ response.headers['X-Cascade'].should == 'pass'
102
+ end
103
+
104
+ it "should return a 404 when the url is a well-encoded but bad array" do
105
+ url = "/media/#{Dragonfly::Serializer.marshal_encode([[:egg, {:some => 'args'}]])}"
106
+ response = request(@server, url)
107
+ response.status.should == 404
108
+ response.body.should == 'Not found'
109
+ response.content_type.should == 'text/plain'
110
+ response.headers['X-Cascade'].should be_nil
111
+ end
112
+
113
+ it "should return a cacheable response" do
114
+ url = "/media/#{@job.serialize}"
115
+ cache = Rack::Cache.new(@server, :entitystore => 'heap:/')
116
+ response = request(cache, url)
117
+ response.status.should == 200
118
+ response.headers['X-Rack-Cache'].should == "miss, store"
119
+ response = request(cache, url)
120
+ response.status.should == 200
121
+ response.headers['X-Rack-Cache'].should == "fresh"
122
+ end
123
+
124
+ end
125
+
126
+ describe "dragonfly response" do
127
+ before(:each) do
128
+ @app = test_app
129
+ @server = Dragonfly::Server.new(@app)
130
+ @server.url_format = '/media/:job'
131
+ end
132
+
133
+ it "should return a simple text response" do
134
+ request(@server, '/dragonfly').should be_a_text_response
135
+ end
136
+
137
+ it "should be configurable" do
138
+ @server.dragonfly_url = '/hello'
139
+ request(@server, '/hello').should be_a_text_response
140
+ request(@server, '/dragonfly').status.should == 404
141
+ end
142
+
143
+ it "should be possible to turn it off" do
144
+ @server.dragonfly_url = nil
145
+ request(@server, '/').status.should == 404
146
+ request(@server, '/dragonfly').status.should == 404
147
+ end
148
+ end
149
+
150
+ describe "urls" do
151
+
152
+ before(:each) do
153
+ @app = test_app
154
+ @server = Dragonfly::Server.new(@app)
155
+ @server.url_format = '/media/:job/:basename.:format'
156
+ @job = @app.fetch('some_uid')
157
+ end
158
+
159
+ it "should generate the correct url when no basename/format" do
160
+ @server.url_for(@job).should == "/media/#{@job.serialize}"
161
+ end
162
+
163
+ it "should generate the correct url when there is a basename and no format" do
164
+ @server.url_for(@job, :basename => 'hello').should == "/media/#{@job.serialize}/hello"
165
+ end
166
+
167
+ it "should generate the correct url when there is a basename and different format" do
168
+ @server.url_for(@job, :basename => 'hello', :format => 'gif').should == "/media/#{@job.serialize}/hello.gif"
169
+ end
170
+
171
+ it "should add extra params to the url query string" do
172
+ @server.url_for(@job, :a => 'thing', :b => 'nuther').should == "/media/#{@job.serialize}?a=thing&b=nuther"
173
+ end
174
+
175
+ it "should add the host to the url if configured" do
176
+ @server.url_host = 'http://some.server:4000'
177
+ @server.url_for(@job).should == "http://some.server:4000/media/#{@job.serialize}"
178
+ end
179
+
180
+ it "should add the host to the url if passed in" do
181
+ @server.url_for(@job, :host => 'https://bungle.com').should == "https://bungle.com/media/#{@job.serialize}"
182
+ end
183
+
184
+ it "should favour the passed in host" do
185
+ @server.url_host = 'http://some.server:4000'
186
+ @server.url_for(@job, :host => 'https://smeedy').should == "https://smeedy/media/#{@job.serialize}"
187
+ end
188
+
189
+ describe "Denial of Service protection" do
190
+ before(:each) do
191
+ @app = test_app
192
+ @server = Dragonfly::Server.new(@app)
193
+ @server.protect_from_dos_attacks = true
194
+ @job = @app.fetch('some_uid')
195
+ end
196
+ it "should generate the correct url" do
197
+ @server.url_for(@job).should == "/#{@job.serialize}?sha=#{@job.sha}"
198
+ end
199
+ end
200
+
201
+ end
202
+
203
+ describe "before_serve callback" do
204
+
205
+ context "with no stop in the callback" do
206
+ before(:each) do
207
+ @app = test_app
208
+ @app.generator.add(:test){ "TEST" }
209
+ @server = Dragonfly::Server.new(@app)
210
+ @job = @app.generate(:test)
211
+ @x = x = ""
212
+ @server.before_serve do |job, env|
213
+ x << job.data
214
+ end
215
+ end
216
+
217
+ it "should be called before serving" do
218
+ response = request(@server, "/#{@job.serialize}")
219
+ response.body.should == 'TEST'
220
+ @x.should == 'TEST'
221
+ end
222
+
223
+ it "should not be called before serving a 404 page" do
224
+ response = request(@server, "blah")
225
+ response.status.should == 404
226
+ @x.should == ""
227
+ end
228
+ end
229
+
230
+ context "with a throw :halt in the callback" do
231
+ before(:each) do
232
+ @app = test_app
233
+ @app.generator.add(:test){ "TEST" }
234
+ @server = Dragonfly::Server.new(@app)
235
+ @job = @app.generate(:test)
236
+ @x = x = ""
237
+ @server.before_serve do |job, env|
238
+ x << job.data
239
+ throw :halt, [200, {}, 'hello']
240
+ end
241
+ end
242
+ it 'return the response instead the job.result' do
243
+ response = request(@server, "/#{@job.serialize}")
244
+ response.body.should == 'hello'
245
+ @x.should == 'TEST'
246
+ end
247
+ end
248
+
249
+ end
250
+
251
+ describe "after_serve callback" do
252
+
253
+ before(:each) do
254
+ @app = test_app
255
+ @app.generator.add(:test){ "TEST" }
256
+ @server = Dragonfly::Server.new(@app)
257
+ @job = @app.generate(:test)
258
+ @x = x = ""
259
+ @server.after_serve do |job, env|
260
+ x << job.data
261
+ end
262
+ end
263
+
264
+ it "should be called after serving" do
265
+ response = request(@server, "/#{@job.serialize}")
266
+ response.body.should == 'TEST'
267
+ @x.should == 'TEST'
268
+ end
269
+
270
+ it "should not be called after serving a 404 page" do
271
+ response = request(@server, "blah")
272
+ response.status.should == 404
273
+ @x.should == ""
274
+ end
275
+
276
+ end
277
+
278
+ end