oahu-dragonfly 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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