dragonfly 0.9.15 → 1.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -8
- data/.travis.yml +11 -0
- data/Gemfile +1 -0
- data/History.md +52 -2
- data/LICENSE +1 -1
- data/README.md +38 -95
- data/dev/grid.jpg +0 -0
- data/dev/irbrc.rb +27 -0
- data/dev/rails_template.rb +38 -0
- data/dev/test.ru +56 -0
- data/dev/test_rails +19 -0
- data/dragonfly.gemspec +3 -21
- data/lib/dragonfly.rb +45 -44
- data/lib/dragonfly/app.rb +175 -96
- data/lib/dragonfly/configurable.rb +71 -170
- data/lib/dragonfly/content.rb +211 -0
- data/lib/dragonfly/core_ext/object.rb +1 -6
- data/lib/dragonfly/file_data_store.rb +197 -0
- data/lib/dragonfly/image_magick/analysers/image_properties.rb +23 -0
- data/lib/dragonfly/image_magick/generators/convert.rb +19 -0
- data/lib/dragonfly/image_magick/generators/plain.rb +26 -0
- data/lib/dragonfly/image_magick/generators/plasma.rb +25 -0
- data/lib/dragonfly/image_magick/generators/text.rb +127 -0
- data/lib/dragonfly/image_magick/plugin.rb +83 -0
- data/lib/dragonfly/image_magick/processors/convert.rb +29 -0
- data/lib/dragonfly/image_magick/processors/encode.rb +18 -0
- data/lib/dragonfly/image_magick/processors/thumb.rb +76 -0
- data/lib/dragonfly/job.rb +118 -134
- data/lib/dragonfly/job_endpoint.rb +2 -0
- data/lib/dragonfly/memory_data_store.rb +34 -0
- data/lib/dragonfly/middleware.rb +5 -3
- data/lib/dragonfly/{active_model_extensions.rb → model.rb} +5 -3
- data/lib/dragonfly/{active_model_extensions → model}/attachment.rb +40 -35
- data/lib/dragonfly/{active_model_extensions → model}/attachment_class_methods.rb +36 -40
- data/lib/dragonfly/model/class_methods.rb +109 -0
- data/lib/dragonfly/{active_model_extensions → model}/instance_methods.rb +2 -2
- data/lib/dragonfly/{active_model_extensions → model}/validations.rb +17 -12
- data/lib/dragonfly/railtie.rb +8 -6
- data/lib/dragonfly/register.rb +27 -0
- data/lib/dragonfly/response.rb +47 -52
- data/lib/dragonfly/routed_endpoint.rb +4 -0
- data/lib/dragonfly/serializer.rb +15 -5
- data/lib/dragonfly/server.rb +56 -29
- data/lib/dragonfly/shell.rb +12 -23
- data/lib/dragonfly/spec/data_store_examples.rb +64 -0
- data/lib/dragonfly/temp_object.rb +32 -47
- data/lib/dragonfly/url_attributes.rb +19 -22
- data/lib/dragonfly/url_mapper.rb +3 -0
- data/lib/dragonfly/utils.rb +12 -0
- data/lib/dragonfly/version.rb +1 -1
- data/lib/dragonfly/whitelist.rb +19 -0
- data/lib/rails/generators/dragonfly/USAGE +8 -0
- data/lib/rails/generators/dragonfly/dragonfly_generator.rb +24 -0
- data/lib/rails/generators/dragonfly/templates/initializer.rb.erb +27 -0
- data/samples/gif.gif +0 -0
- data/spec/dragonfly/app_spec.rb +270 -64
- data/spec/dragonfly/configurable_spec.rb +142 -418
- data/spec/dragonfly/content_spec.rb +353 -0
- data/spec/dragonfly/cookie_monster_spec.rb +2 -1
- data/spec/dragonfly/file_data_store_spec.rb +301 -0
- data/spec/dragonfly/image_magick/analysers/image_properties_spec.rb +20 -0
- data/spec/dragonfly/image_magick/generators/convert_spec.rb +19 -0
- data/spec/dragonfly/image_magick/generators/plain_spec.rb +50 -0
- data/spec/dragonfly/image_magick/generators/plasma_spec.rb +32 -0
- data/spec/dragonfly/image_magick/generators/text_spec.rb +77 -0
- data/spec/dragonfly/image_magick/plugin_spec.rb +131 -0
- data/spec/dragonfly/image_magick/processors/convert_spec.rb +56 -0
- data/spec/dragonfly/image_magick/processors/thumb_spec.rb +173 -0
- data/spec/dragonfly/job_endpoint_spec.rb +30 -73
- data/spec/dragonfly/job_spec.rb +280 -608
- data/spec/dragonfly/memory_data_store_spec.rb +20 -0
- data/spec/dragonfly/middleware_spec.rb +47 -27
- data/spec/dragonfly/{active_model_extensions → model}/model_spec.rb +331 -555
- data/spec/dragonfly/model/validations_spec.rb +196 -0
- data/spec/dragonfly/register_spec.rb +35 -0
- data/spec/dragonfly/routed_endpoint_spec.rb +6 -6
- data/spec/dragonfly/serializer_spec.rb +13 -15
- data/spec/dragonfly/server_spec.rb +122 -46
- data/spec/dragonfly/shell_spec.rb +43 -24
- data/spec/dragonfly/temp_object_spec.rb +69 -94
- data/spec/dragonfly/url_attributes_spec.rb +49 -0
- data/spec/dragonfly/utils_spec.rb +32 -0
- data/spec/dragonfly/whitelist_spec.rb +30 -0
- data/spec/dragonfly_spec.rb +43 -0
- data/spec/fixtures/deprecated_stored_content/eggs.bonus +1 -0
- data/spec/fixtures/deprecated_stored_content/eggs.bonus.meta +1 -0
- data/spec/functional/configuration_spec.rb +19 -0
- data/spec/functional/model_urls_spec.rb +43 -41
- data/spec/functional/remote_on_the_fly_spec.rb +14 -16
- data/spec/functional/shell_commands_spec.rb +24 -14
- data/spec/functional/to_response_spec.rb +10 -10
- data/spec/functional/urls_spec.rb +5 -3
- data/spec/spec_helper.rb +23 -28
- data/spec/support/argument_matchers.rb +7 -8
- data/spec/support/image_matchers.rb +14 -36
- data/spec/support/model_helpers.rb +97 -0
- data/spec/support/simple_matchers.rb +12 -0
- metadata +92 -393
- data/.yardopts +0 -29
- data/Rakefile +0 -36
- data/config.ru +0 -14
- data/docs.watchr +0 -1
- data/extra_docs/Analysers.md +0 -68
- data/extra_docs/Caching.md +0 -23
- data/extra_docs/Configuration.md +0 -149
- data/extra_docs/Couch.md +0 -49
- data/extra_docs/DataStorage.md +0 -226
- data/extra_docs/Encoding.md +0 -67
- data/extra_docs/ExampleUseCases.md +0 -116
- data/extra_docs/GeneralUsage.md +0 -105
- data/extra_docs/Generators.md +0 -68
- data/extra_docs/Heroku.md +0 -50
- data/extra_docs/ImageMagick.md +0 -136
- data/extra_docs/Index.md +0 -33
- data/extra_docs/MimeTypes.md +0 -40
- data/extra_docs/Models.md +0 -441
- data/extra_docs/Mongo.md +0 -42
- data/extra_docs/Processing.md +0 -77
- data/extra_docs/Rack.md +0 -52
- data/extra_docs/Rails2.md +0 -57
- data/extra_docs/Rails3.md +0 -56
- data/extra_docs/ServingRemotely.md +0 -104
- data/extra_docs/Sinatra.md +0 -25
- data/extra_docs/URLs.md +0 -203
- data/features/images.feature +0 -47
- data/features/no_processing.feature +0 -14
- data/features/rails.feature +0 -8
- data/features/steps/common_steps.rb +0 -8
- data/features/steps/dragonfly_steps.rb +0 -66
- data/features/steps/rails_steps.rb +0 -40
- data/features/support/env.rb +0 -13
- data/features/support/setup.rb +0 -41
- data/fixtures/rails/files/app/models/album.rb +0 -6
- data/fixtures/rails/files/app/views/albums/new.html.erb +0 -7
- data/fixtures/rails/files/app/views/albums/show.html.erb +0 -6
- data/fixtures/rails/files/config/initializers/dragonfly.rb +0 -4
- data/fixtures/rails/files/features/manage_album_images.feature +0 -38
- data/fixtures/rails/files/features/step_definitions/helper_steps.rb +0 -7
- data/fixtures/rails/files/features/step_definitions/image_steps.rb +0 -25
- data/fixtures/rails/files/features/step_definitions/web_steps.rb +0 -189
- data/fixtures/rails/files/features/support/paths.rb +0 -17
- data/fixtures/rails/files/features/text_images.feature +0 -7
- data/fixtures/rails/template.rb +0 -20
- data/irbrc.rb +0 -19
- data/lib/dragonfly/active_model_extensions/class_methods.rb +0 -98
- data/lib/dragonfly/analyser.rb +0 -58
- data/lib/dragonfly/analysis/file_command_analyser.rb +0 -33
- data/lib/dragonfly/analysis/image_magick_analyser.rb +0 -6
- data/lib/dragonfly/config/heroku.rb +0 -26
- data/lib/dragonfly/config/image_magick.rb +0 -6
- data/lib/dragonfly/config/rails.rb +0 -20
- data/lib/dragonfly/data_storage.rb +0 -11
- data/lib/dragonfly/data_storage/couch_data_store.rb +0 -83
- data/lib/dragonfly/data_storage/file_data_store.rb +0 -144
- data/lib/dragonfly/data_storage/mongo_data_store.rb +0 -96
- data/lib/dragonfly/data_storage/s3data_store.rb +0 -168
- data/lib/dragonfly/encoder.rb +0 -13
- data/lib/dragonfly/encoding/image_magick_encoder.rb +0 -6
- data/lib/dragonfly/function_manager.rb +0 -67
- data/lib/dragonfly/generation/image_magick_generator.rb +0 -6
- data/lib/dragonfly/generator.rb +0 -9
- data/lib/dragonfly/image_magick/analyser.rb +0 -53
- data/lib/dragonfly/image_magick/config.rb +0 -44
- data/lib/dragonfly/image_magick/encoder.rb +0 -57
- data/lib/dragonfly/image_magick/generator.rb +0 -147
- data/lib/dragonfly/image_magick/processor.rb +0 -114
- data/lib/dragonfly/image_magick/utils.rb +0 -46
- data/lib/dragonfly/image_magick_utils.rb +0 -4
- data/lib/dragonfly/job_builder.rb +0 -39
- data/lib/dragonfly/job_definitions.rb +0 -30
- data/lib/dragonfly/loggable.rb +0 -28
- data/lib/dragonfly/processing/image_magick_processor.rb +0 -6
- data/lib/dragonfly/processor.rb +0 -9
- data/lib/dragonfly/rails/images.rb +0 -32
- data/lib/dragonfly/simple_cache.rb +0 -23
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +0 -95
- data/spec/dragonfly/analyser_spec.rb +0 -123
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +0 -49
- data/spec/dragonfly/data_storage/couch_data_store_spec.rb +0 -84
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +0 -308
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +0 -81
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +0 -277
- data/spec/dragonfly/data_storage/shared_data_store_examples.rb +0 -77
- data/spec/dragonfly/function_manager_spec.rb +0 -154
- data/spec/dragonfly/image_magick/analyser_spec.rb +0 -73
- data/spec/dragonfly/image_magick/encoder_spec.rb +0 -46
- data/spec/dragonfly/image_magick/generator_spec.rb +0 -178
- data/spec/dragonfly/image_magick/processor_spec.rb +0 -293
- data/spec/dragonfly/job_builder_spec.rb +0 -37
- data/spec/dragonfly/job_definitions_spec.rb +0 -57
- data/spec/dragonfly/loggable_spec.rb +0 -80
- data/spec/dragonfly/simple_cache_spec.rb +0 -27
- data/spec/dragonfly/url_attributes.rb +0 -47
- data/spec/functional/deprecations_spec.rb +0 -51
- data/spec/functional/image_magick_app_spec.rb +0 -27
- data/spec/test_imagemagick.ru +0 -49
- data/yard/handlers/configurable_attr_handler.rb +0 -38
- data/yard/setup.rb +0 -15
- data/yard/templates/default/fulldoc/html/css/common.css +0 -109
- data/yard/templates/default/layout/html/layout.erb +0 -93
- data/yard/templates/default/module/html/configuration_summary.erb +0 -31
- data/yard/templates/default/module/setup.rb +0 -17
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dragonfly/model/validations'
|
3
|
+
|
4
|
+
describe Dragonfly::Model::Validations do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@app = test_app
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "validates_presence_of" do
|
11
|
+
before(:each) do
|
12
|
+
@item_class = new_model_class('Item', :preview_image_uid) do
|
13
|
+
dragonfly_accessor :preview_image
|
14
|
+
validates_presence_of :preview_image
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be valid if set" do
|
19
|
+
@item_class.new(:preview_image => "1234567890").should be_valid
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be invalid if not set" do
|
23
|
+
@item_class.new.should_not be_valid
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "validates_size_of" do
|
28
|
+
before(:each) do
|
29
|
+
@item_class = new_model_class('Item', :preview_image_uid) do
|
30
|
+
dragonfly_accessor :preview_image
|
31
|
+
validates_size_of :preview_image, :within => (6..10)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be valid if ok" do
|
36
|
+
@item_class.new(:preview_image => "1234567890").should be_valid
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be invalid if too small" do
|
40
|
+
@item_class.new(:preview_image => "12345").should_not be_valid
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "validates_property" do
|
45
|
+
|
46
|
+
before(:each) do
|
47
|
+
@item_class = new_model_class('Item',
|
48
|
+
:preview_image_uid,
|
49
|
+
:other_image_uid,
|
50
|
+
:title
|
51
|
+
) do
|
52
|
+
extend Dragonfly::Model::Validations
|
53
|
+
|
54
|
+
dragonfly_accessor :preview_image
|
55
|
+
dragonfly_accessor :other_image
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
before(:each) do
|
60
|
+
@item = @item_class.new(:preview_image => "1234567890")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should be valid if the property is correct" do
|
64
|
+
@item_class.class_eval do
|
65
|
+
validates_property :gungle, :of => :preview_image, :as => 'bungo'
|
66
|
+
end
|
67
|
+
@item.preview_image = "something"
|
68
|
+
@item.preview_image.should_receive(:gungle).and_return('bungo')
|
69
|
+
@item.should be_valid
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should be valid if nil, if not validated on presence (even with validates_property)" do
|
73
|
+
@item_class.class_eval do
|
74
|
+
validates_property :size, :of => :preview_image, :as => 234
|
75
|
+
end
|
76
|
+
@item.preview_image = nil
|
77
|
+
@item.should be_valid
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should be invalid if the property is nil" do
|
81
|
+
@item_class.class_eval do
|
82
|
+
validates_property :gungle, :of => :preview_image, :in => ['bungo', 'jerry']
|
83
|
+
end
|
84
|
+
@item.preview_image = "something"
|
85
|
+
@item.preview_image.should_receive(:gungle).and_return(nil)
|
86
|
+
@item.should_not be_valid
|
87
|
+
@item.errors[:preview_image].should == ["gungle is incorrect. It needs to be one of 'bungo', 'jerry'"]
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be invalid if the property is wrong" do
|
91
|
+
@item_class.class_eval do
|
92
|
+
validates_property :gungle, :of => :preview_image, :in => ['bungo', 'jerry']
|
93
|
+
end
|
94
|
+
@item.preview_image = "something"
|
95
|
+
@item.preview_image.should_receive(:gungle).and_return('spangle')
|
96
|
+
@item.should_not be_valid
|
97
|
+
@item.errors[:preview_image].should == ["gungle is incorrect. It needs to be one of 'bungo', 'jerry', but was 'spangle'"]
|
98
|
+
end
|
99
|
+
|
100
|
+
it "is invalid if the property raises" do
|
101
|
+
@item_class.class_eval do
|
102
|
+
validates_property :gungle, :of => :preview_image, :as => 'bungo'
|
103
|
+
end
|
104
|
+
@item.preview_image = "something"
|
105
|
+
@item.preview_image.should_receive(:gungle).and_raise(RuntimeError, "yikes!")
|
106
|
+
@item.should_not be_valid
|
107
|
+
@item.errors[:preview_image].should == ["gungle is incorrect. It needs to be 'bungo'"]
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should work for a range" do
|
111
|
+
@item_class.class_eval do
|
112
|
+
validates_property :gungle, :of => :preview_image, :in => (0..2)
|
113
|
+
end
|
114
|
+
@item.preview_image = "something"
|
115
|
+
@item.preview_image.should_receive(:gungle).and_return(3)
|
116
|
+
@item.should_not be_valid
|
117
|
+
@item.errors[:preview_image].should == ["gungle is incorrect. It needs to be between 0 and 2, but was '3'"]
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should validate individually" do
|
121
|
+
@item_class.class_eval do
|
122
|
+
validates_property :size, :of => [:preview_image, :other_image], :as => 9
|
123
|
+
end
|
124
|
+
@item.preview_image = "something"
|
125
|
+
@item.other_image = "something else"
|
126
|
+
@item.should_not be_valid
|
127
|
+
@item.errors[:preview_image].should == []
|
128
|
+
@item.errors[:other_image].should == ["size is incorrect. It needs to be '9', but was '14'"]
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should include standard extra options like 'if' on mime type validation" do
|
132
|
+
@item_class.class_eval do
|
133
|
+
validates_property :size, :of => :preview_image, :as => 4, :if => :its_friday
|
134
|
+
end
|
135
|
+
@item.preview_image = '13 characters'
|
136
|
+
@item.should_receive(:its_friday).and_return(false)
|
137
|
+
@item.should be_valid
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should allow case sensitivity to be turned off when :as is specified" do
|
141
|
+
@item_class.class_eval do
|
142
|
+
validates_property :gungle, :of => :preview_image, :as => 'oKtHeN', :case_sensitive => false
|
143
|
+
end
|
144
|
+
@item.preview_image = "something"
|
145
|
+
@item.preview_image.should_receive(:gungle).and_return('OKTHEN')
|
146
|
+
@item.should be_valid
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should allow case sensitivity to be turned off when :in is specified" do
|
150
|
+
@item_class.class_eval do
|
151
|
+
validates_property :gungle, :of => :preview_image, :in => ['oKtHeN'], :case_sensitive => false
|
152
|
+
end
|
153
|
+
@item.preview_image = "something"
|
154
|
+
@item.preview_image.should_receive(:gungle).and_return('OKTHEN')
|
155
|
+
@item.should be_valid
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should require either :as or :in as an argument" do
|
159
|
+
lambda{
|
160
|
+
@item_class.class_eval do
|
161
|
+
validates_property :mime_type, :of => :preview_image
|
162
|
+
end
|
163
|
+
}.should raise_error(ArgumentError)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should require :of as an argument" do
|
167
|
+
lambda{
|
168
|
+
@item_class.class_eval do
|
169
|
+
validates_property :mime_type, :as => 'hi/there'
|
170
|
+
end
|
171
|
+
}.should raise_error(ArgumentError)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should allow for custom messages" do
|
175
|
+
@item_class.class_eval do
|
176
|
+
validates_property :size, :of => :preview_image, :as => 4, :message => "errado, seu burro"
|
177
|
+
end
|
178
|
+
@item.preview_image = "something"
|
179
|
+
@item.should_not be_valid
|
180
|
+
@item.errors[:preview_image].should == ["errado, seu burro"]
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should allow for custom messages including access to the property name and expected/allowed values" do
|
184
|
+
@item_class.class_eval do
|
185
|
+
validates_property :size, :of => :preview_image, :as => 4,
|
186
|
+
:message => proc{|actual, model| "Unlucky #{model.title}! Was #{actual}" }
|
187
|
+
end
|
188
|
+
@item.title = 'scubby'
|
189
|
+
@item.preview_image = "too long"
|
190
|
+
@item.should_not be_valid
|
191
|
+
@item.errors[:preview_image].should == ["Unlucky scubby! Was 8"]
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dragonfly::Register do
|
4
|
+
|
5
|
+
let (:register) { Dragonfly::Register.new }
|
6
|
+
let (:thing) { proc{ "BOO" } }
|
7
|
+
|
8
|
+
it "adds an item" do
|
9
|
+
register.add(:thing, thing)
|
10
|
+
register.get(:thing).should == thing
|
11
|
+
end
|
12
|
+
|
13
|
+
it "adds from a block" do
|
14
|
+
register.add(:thing, &thing)
|
15
|
+
register.get(:thing).should == thing
|
16
|
+
end
|
17
|
+
|
18
|
+
it "raises an error if neither are given" do
|
19
|
+
expect {
|
20
|
+
register.add(:something)
|
21
|
+
}.to raise_error(ArgumentError)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "raises an error if getting one that doesn't exist" do
|
25
|
+
expect {
|
26
|
+
register.get(:thing)
|
27
|
+
}.to raise_error(Dragonfly::Register::NotFound)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "allows getting with a string" do
|
31
|
+
register.add(:thing, thing)
|
32
|
+
register.get('thing').should == thing
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -15,7 +15,7 @@ describe Dragonfly::RoutedEndpoint do
|
|
15
15
|
@endpoint = Dragonfly::RoutedEndpoint.new(@app) {|params, app|
|
16
16
|
app.fetch(params[:uid])
|
17
17
|
}
|
18
|
-
@app.
|
18
|
+
@uid = @app.store('wassup')
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should raise an error when there are no routing parameters" do
|
@@ -33,20 +33,20 @@ describe Dragonfly::RoutedEndpoint do
|
|
33
33
|
}.each do |name, key|
|
34
34
|
|
35
35
|
it "should work with #{name} routing args" do
|
36
|
-
response = response_for @endpoint.call(env_for('/blah', key => {:uid =>
|
36
|
+
response = response_for @endpoint.call(env_for('/blah', key => {:uid => @uid}))
|
37
37
|
response.body.should == 'wassup'
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should merge with query parameters" do
|
43
|
-
env = Rack::MockRequest.env_for(
|
43
|
+
env = Rack::MockRequest.env_for("/big/buns?uid=#{@uid}", 'dragonfly.params' => {:something => 'else'})
|
44
44
|
response = response_for @endpoint.call(env)
|
45
45
|
response.body.should == 'wassup'
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
it "should have nice inspect output" do
|
49
|
-
@endpoint.inspect.should =~ /<Dragonfly::RoutedEndpoint for app :
|
49
|
+
@endpoint.inspect.should =~ /<Dragonfly::RoutedEndpoint for app :default >/
|
50
50
|
end
|
51
51
|
|
52
52
|
end
|
@@ -45,30 +45,30 @@ describe Dragonfly::Serializer do
|
|
45
45
|
[{:this => 'should', :work => [3, 5.3, nil, {false => 'egg'}]}, [], true]
|
46
46
|
].each do |object|
|
47
47
|
it "should correctly marshal encode #{object.inspect} properly with no padding/line break" do
|
48
|
-
encoded =
|
48
|
+
encoded = marshal_b64_encode(object)
|
49
49
|
encoded.should be_a(String)
|
50
50
|
encoded.should_not =~ /\n|=/
|
51
51
|
end
|
52
52
|
it "should correctly marshal encode and decode #{object.inspect} to the same object" do
|
53
|
-
|
53
|
+
marshal_b64_decode(marshal_b64_encode(object)).should == object
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
describe "
|
57
|
+
describe "marshal_b64_decode" do
|
58
58
|
it "should raise an error if the string passed in is empty" do
|
59
59
|
lambda{
|
60
|
-
|
60
|
+
marshal_b64_decode('')
|
61
61
|
}.should raise_error(Dragonfly::Serializer::BadString)
|
62
62
|
end
|
63
63
|
it "should raise an error if the string passed in is gobbledeegook" do
|
64
64
|
lambda{
|
65
|
-
|
65
|
+
marshal_b64_decode('ahasdkjfhasdkfjh')
|
66
66
|
}.should raise_error(Dragonfly::Serializer::BadString)
|
67
67
|
end
|
68
68
|
describe "potentially harmful strings" do
|
69
69
|
it "doesn't raise if not flagged to check for malicious strings" do
|
70
70
|
class C; end
|
71
|
-
|
71
|
+
marshal_b64_decode('BAhvOgZDBjoOQF9fc2VuZF9faQY').should be_a(C)
|
72
72
|
end
|
73
73
|
['_', 'hello', 'h2', '__send__', 'F'].each do |variable_name|
|
74
74
|
it "raises if flagged to check for malicious strings and finds one" do
|
@@ -77,7 +77,7 @@ describe Dragonfly::Serializer do
|
|
77
77
|
c.instance_eval{ instance_variable_set("@#{variable_name}", 1) }
|
78
78
|
string = Dragonfly::Serializer.b64_encode(Marshal.dump(c))
|
79
79
|
lambda{
|
80
|
-
|
80
|
+
marshal_b64_decode(string, :check_malicious => true)
|
81
81
|
}.should raise_error(Dragonfly::Serializer::MaliciousString)
|
82
82
|
end
|
83
83
|
end
|
@@ -90,27 +90,25 @@ describe Dragonfly::Serializer do
|
|
90
90
|
[{'this' => 'should', 'work' => [3, 5.3, nil, {'egg' => false}]}, [], true]
|
91
91
|
].each do |object|
|
92
92
|
it "should correctly json encode #{object.inspect} properly with no padding/line break" do
|
93
|
-
encoded =
|
93
|
+
encoded = json_b64_encode(object)
|
94
94
|
encoded.should be_a(String)
|
95
95
|
encoded.should_not =~ /\n|=/
|
96
96
|
end
|
97
|
+
|
97
98
|
it "should correctly json encode and decode #{object.inspect} to the same object" do
|
98
|
-
|
99
|
+
json_b64_decode(json_b64_encode(object)).should == object
|
99
100
|
end
|
100
101
|
end
|
101
102
|
|
102
|
-
describe "
|
103
|
-
it "optionally symbolizes keys" do
|
104
|
-
json_decode(json_encode('a' => 1), :symbolize_keys => true).should == {:a => 1}
|
105
|
-
end
|
103
|
+
describe "json_b64_decode" do
|
106
104
|
it "should raise an error if the string passed in is empty" do
|
107
105
|
lambda{
|
108
|
-
|
106
|
+
json_b64_decode('')
|
109
107
|
}.should raise_error(Dragonfly::Serializer::BadString)
|
110
108
|
end
|
111
109
|
it "should raise an error if the string passed in is gobbledeegook" do
|
112
110
|
lambda{
|
113
|
-
|
111
|
+
json_b64_decode('ahasdkjfhasdkfjh')
|
114
112
|
}.should raise_error(Dragonfly::Serializer::BadString)
|
115
113
|
end
|
116
114
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rack/mock'
|
3
|
-
require 'rack/cache'
|
4
3
|
|
5
4
|
def request(app, path)
|
6
5
|
Rack::MockRequest.new(app).get(path)
|
@@ -53,13 +52,9 @@ describe Dragonfly::Server do
|
|
53
52
|
|
54
53
|
it "should return a cacheable response" do
|
55
54
|
url = "/media/#{@job.serialize}"
|
56
|
-
|
57
|
-
response = request(cache, url)
|
58
|
-
response.status.should == 200
|
59
|
-
response.headers['X-Rack-Cache'].should == "miss, store"
|
60
|
-
response = request(cache, url)
|
55
|
+
response = request(@server, url)
|
61
56
|
response.status.should == 200
|
62
|
-
response.headers['
|
57
|
+
response.headers['Cache-Control'].should == "public, max-age=31536000"
|
63
58
|
end
|
64
59
|
|
65
60
|
it "should return successfully even if the job is in the query string" do
|
@@ -113,7 +108,7 @@ describe Dragonfly::Server do
|
|
113
108
|
end
|
114
109
|
|
115
110
|
it "should return a 404 when the url is a well-encoded but bad array" do
|
116
|
-
url = "/media/#{Dragonfly::Serializer.
|
111
|
+
url = "/media/#{Dragonfly::Serializer.json_b64_encode([['egg', {'some' => 'args'}]])}"
|
117
112
|
response = request(@server, url)
|
118
113
|
response.status.should == 404
|
119
114
|
response.body.should == 'Not found'
|
@@ -121,21 +116,52 @@ describe Dragonfly::Server do
|
|
121
116
|
response.headers['X-Cascade'].should be_nil
|
122
117
|
end
|
123
118
|
|
124
|
-
it "should return a 403 Forbidden when someone uses
|
125
|
-
response = request(@server, "/media/#{@app.
|
119
|
+
it "should return a 403 Forbidden when someone uses fetch_url" do
|
120
|
+
response = request(@server, "/media/#{@app.fetch_url('some.url').serialize}")
|
126
121
|
response.status.should == 403
|
127
122
|
response.body.should == 'Forbidden'
|
128
123
|
response.content_type.should == 'text/plain'
|
129
124
|
end
|
125
|
+
end
|
130
126
|
|
131
|
-
|
132
|
-
|
127
|
+
describe "whitelists" do
|
128
|
+
def assert_ok(job)
|
129
|
+
response = request(@server, "/media/#{job.serialize}")
|
130
|
+
response.status.should == 200
|
131
|
+
end
|
132
|
+
|
133
|
+
def assert_forbidden(job)
|
134
|
+
response = request(@server, "/media/#{job.serialize}")
|
133
135
|
response.status.should == 403
|
134
136
|
response.body.should == 'Forbidden'
|
135
137
|
response.content_type.should == 'text/plain'
|
136
138
|
end
|
137
|
-
end
|
138
139
|
|
140
|
+
describe "fetch_file" do
|
141
|
+
it "should return a 403 Forbidden when someone uses fetch_file " do
|
142
|
+
assert_forbidden @app.fetch_file('samples/egg.png')
|
143
|
+
end
|
144
|
+
|
145
|
+
it "returns OK when on whitelist (using full path)" do
|
146
|
+
@server.add_to_fetch_file_whitelist [File.expand_path('samples/egg.png')]
|
147
|
+
assert_ok @app.fetch_file('samples/egg.png')
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "fetch_url" do
|
152
|
+
let (:url) {'some.org/path:3000/boogie?yes=please'}
|
153
|
+
|
154
|
+
it "should return a 403 Forbidden when someone uses fetch_url " do
|
155
|
+
assert_forbidden @app.fetch_url(url)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "returns OK when on whitelist (using full url)" do
|
159
|
+
stub_request(:get, url).to_return(:status => 200)
|
160
|
+
@server.add_to_fetch_url_whitelist ["http://#{url}"]
|
161
|
+
assert_ok @app.fetch_url(url)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
139
165
|
end
|
140
166
|
|
141
167
|
describe "dragonfly response" do
|
@@ -164,52 +190,102 @@ describe Dragonfly::Server do
|
|
164
190
|
|
165
191
|
describe "urls" do
|
166
192
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
@server.url_format = '/media/:job/:basename.:format'
|
171
|
-
@job = @app.fetch('some_uid')
|
172
|
-
end
|
193
|
+
let (:app) { test_app }
|
194
|
+
let (:server) { Dragonfly::Server.new(app) }
|
195
|
+
let (:job) { app.fetch("some_uid") }
|
173
196
|
|
174
|
-
|
175
|
-
|
176
|
-
|
197
|
+
describe "params" do
|
198
|
+
before(:each) do
|
199
|
+
server.url_format = '/media/:job/:zoo'
|
200
|
+
end
|
201
|
+
it "substitutes the relevant params" do
|
202
|
+
server.url_for(job).should == "/media/#{job.serialize}"
|
203
|
+
end
|
204
|
+
it "adds given params" do
|
205
|
+
server.url_for(job, :zoo => 'jokes', :on => 'me').should == "/media/#{job.serialize}/jokes?on=me"
|
206
|
+
end
|
207
|
+
it "uses the url_attr if it exists" do
|
208
|
+
job.url_attributes.zoo = 'hair'
|
209
|
+
server.url_for(job).should == "/media/#{job.serialize}/hair"
|
210
|
+
end
|
211
|
+
it "doesn't add any url_attributes that aren't needed" do
|
212
|
+
job.url_attributes.gump = 'flub'
|
213
|
+
server.url_for(job).should == "/media/#{job.serialize}"
|
214
|
+
end
|
215
|
+
it "overrides if a param is passed in" do
|
216
|
+
job.url_attributes.zoo = 'hair'
|
217
|
+
server.url_for(job, :zoo => 'dare').should == "/media/#{job.serialize}/dare"
|
218
|
+
end
|
177
219
|
|
178
|
-
|
179
|
-
|
180
|
-
|
220
|
+
describe "basename" do
|
221
|
+
before(:each) do
|
222
|
+
server.url_format = '/:job/:basename'
|
223
|
+
end
|
224
|
+
it "should use the name" do
|
225
|
+
job.url_attributes.name = 'hello.egg'
|
226
|
+
server.url_for(job).should == "/#{job.serialize}/hello"
|
227
|
+
end
|
228
|
+
it "should not set if neither exist" do
|
229
|
+
server.url_for(job).should == "/#{job.serialize}"
|
230
|
+
end
|
231
|
+
end
|
181
232
|
|
182
|
-
|
183
|
-
|
233
|
+
describe "ext" do
|
234
|
+
before(:each) do
|
235
|
+
server.url_format = '/:job.:ext'
|
236
|
+
end
|
237
|
+
it "should use the name" do
|
238
|
+
job.url_attributes.name = 'hello.egg'
|
239
|
+
server.url_for(job).should == "/#{job.serialize}.egg"
|
240
|
+
end
|
241
|
+
it "should not set if neither exist" do
|
242
|
+
server.url_for(job).should == "/#{job.serialize}"
|
243
|
+
end
|
244
|
+
end
|
184
245
|
end
|
185
246
|
|
186
|
-
|
187
|
-
|
188
|
-
|
247
|
+
describe "host" do
|
248
|
+
it "should add the host to the url if configured" do
|
249
|
+
server.url_host = 'http://some.server:4000'
|
250
|
+
server.url_for(job).should == "http://some.server:4000/#{job.serialize}"
|
251
|
+
end
|
189
252
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
end
|
253
|
+
it "should add the host to the url if passed in" do
|
254
|
+
server.url_for(job, :host => 'https://bungle.com').should == "https://bungle.com/#{job.serialize}"
|
255
|
+
end
|
194
256
|
|
195
|
-
|
196
|
-
|
257
|
+
it "should favour the passed in host" do
|
258
|
+
server.url_host = 'http://some.server:4000'
|
259
|
+
server.url_for(job, :host => 'https://smeedy').should == "https://smeedy/#{job.serialize}"
|
260
|
+
end
|
197
261
|
end
|
198
262
|
|
199
|
-
|
200
|
-
|
201
|
-
|
263
|
+
describe "path_prefix" do
|
264
|
+
before do
|
265
|
+
server.url_format = '/media/:job'
|
266
|
+
end
|
267
|
+
|
268
|
+
it "adds the path_prefix to the url if configured" do
|
269
|
+
server.url_path_prefix = '/logs'
|
270
|
+
server.url_for(job).should == "/logs/media/#{job.serialize}"
|
271
|
+
end
|
272
|
+
|
273
|
+
it "favours the passed in path_prefix" do
|
274
|
+
server.url_path_prefix = '/logs'
|
275
|
+
server.url_for(job, :path_prefix => '/bugs').should == "/bugs/media/#{job.serialize}"
|
276
|
+
end
|
277
|
+
|
278
|
+
it "goes after the host" do
|
279
|
+
server.url_for(job, :path_prefix => '/bugs', :host => 'http://wassup').should == "http://wassup/bugs/media/#{job.serialize}"
|
280
|
+
end
|
202
281
|
end
|
203
282
|
|
204
283
|
describe "Denial of Service protection" do
|
205
284
|
before(:each) do
|
206
|
-
|
207
|
-
@server = Dragonfly::Server.new(@app)
|
208
|
-
@server.protect_from_dos_attacks = true
|
209
|
-
@job = @app.fetch('some_uid')
|
285
|
+
server.protect_from_dos_attacks = true
|
210
286
|
end
|
211
287
|
it "should generate the correct url" do
|
212
|
-
|
288
|
+
server.url_for(job).should == "/#{job.serialize}?sha=#{job.sha}"
|
213
289
|
end
|
214
290
|
end
|
215
291
|
|
@@ -219,7 +295,7 @@ describe Dragonfly::Server do
|
|
219
295
|
|
220
296
|
before(:each) do
|
221
297
|
@app = test_app
|
222
|
-
@app.
|
298
|
+
@app.add_generator(:test){|content| content.update("TEST") }
|
223
299
|
@server = Dragonfly::Server.new(@app)
|
224
300
|
@job = @app.generate(:test)
|
225
301
|
end
|
@@ -258,7 +334,7 @@ describe Dragonfly::Server do
|
|
258
334
|
end
|
259
335
|
|
260
336
|
it "should not apply the job if not asked to" do
|
261
|
-
@app.
|
337
|
+
@app.generators.get(:test).should_not_receive(:call)
|
262
338
|
response = request(@server, "/#{@job.serialize}")
|
263
339
|
end
|
264
340
|
end
|