dragonfly 1.0 → 1.0.1

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.

Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +1 -4
  4. data/History.md +17 -0
  5. data/README.md +6 -2
  6. data/Rakefile +1 -0
  7. data/dragonfly.gemspec +17 -1
  8. data/lib/dragonfly/app.rb +10 -1
  9. data/lib/dragonfly/file_data_store.rb +1 -1
  10. data/lib/dragonfly/image_magick/plugin.rb +3 -2
  11. data/lib/dragonfly/job.rb +5 -178
  12. data/lib/dragonfly/job/fetch.rb +19 -0
  13. data/lib/dragonfly/job/fetch_file.rb +27 -0
  14. data/lib/dragonfly/job/fetch_url.rb +75 -0
  15. data/lib/dragonfly/job/generate.rb +27 -0
  16. data/lib/dragonfly/job/process.rb +27 -0
  17. data/lib/dragonfly/job/step.rb +44 -0
  18. data/lib/dragonfly/model/attachment.rb +0 -2
  19. data/lib/dragonfly/model/class_methods.rb +5 -0
  20. data/lib/dragonfly/rails/images.rb +1 -0
  21. data/lib/dragonfly/response.rb +11 -2
  22. data/lib/dragonfly/routed_endpoint.rb +15 -5
  23. data/lib/dragonfly/serializer.rb +2 -2
  24. data/lib/dragonfly/shell.rb +28 -5
  25. data/lib/dragonfly/version.rb +1 -1
  26. data/spec/dragonfly/file_data_store_spec.rb +29 -32
  27. data/spec/dragonfly/job/fetch_file_spec.rb +26 -0
  28. data/spec/dragonfly/job/fetch_spec.rb +26 -0
  29. data/spec/dragonfly/job/fetch_url_spec.rb +123 -0
  30. data/spec/dragonfly/job/generate_spec.rb +28 -0
  31. data/spec/dragonfly/job/process_spec.rb +28 -0
  32. data/spec/dragonfly/job_endpoint_spec.rb +17 -0
  33. data/spec/dragonfly/job_spec.rb +0 -187
  34. data/spec/dragonfly/model/model_spec.rb +27 -12
  35. data/spec/dragonfly/routed_endpoint_spec.rb +69 -28
  36. data/spec/dragonfly/shell_spec.rb +2 -2
  37. data/spec/support/simple_matchers.rb +1 -1
  38. metadata +43 -16
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dragonfly::Job::Generate do
4
+
5
+ let (:app) { test_app }
6
+ let (:job) { Dragonfly::Job.new(app) }
7
+
8
+ before :each do
9
+ app.add_generator(:plasma){}
10
+ end
11
+
12
+ it "adds a step" do
13
+ job.generate!(:plasma, 20)
14
+ job.steps.should match_steps([Dragonfly::Job::Generate])
15
+ end
16
+
17
+ it "uses the generator when applied" do
18
+ job.generate!(:plasma, 20)
19
+ app.get_generator(:plasma).should_receive(:call).with(job.content, 20)
20
+ job.apply
21
+ end
22
+
23
+ it "updates the url if method exists" do
24
+ app.get_generator(:plasma).should_receive(:update_url).with(job.url_attributes, 20)
25
+ job.generate!(:plasma, 20)
26
+ end
27
+
28
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dragonfly::Job::Process do
4
+
5
+ let (:app) { test_app }
6
+ let (:job) { Dragonfly::Job.new(app) }
7
+
8
+ before :each do
9
+ app.add_processor(:resize){}
10
+ end
11
+
12
+ it "adds a step" do
13
+ job.process!(:resize, '20x30')
14
+ job.steps.should match_steps([Dragonfly::Job::Process])
15
+ end
16
+
17
+ it "should use the processor when applied" do
18
+ job.process!(:resize, '20x30')
19
+ app.get_processor(:resize).should_receive(:call).with(job.content, '20x30')
20
+ job.apply
21
+ end
22
+
23
+ it "should call update_url immediately with the url_attributes" do
24
+ app.get_processor(:resize).should_receive(:update_url).with(job.url_attributes, '20x30')
25
+ job.process!(:resize, '20x30')
26
+ end
27
+
28
+ end
@@ -94,6 +94,23 @@ describe Dragonfly::JobEndpoint do
94
94
  response.status.should == 500
95
95
  end
96
96
 
97
+ describe "default content disposition file name" do
98
+ before do
99
+ uid = @app.store("GUNGLE", 'name' => 'güng.txt')
100
+ @job = @app.fetch(uid)
101
+ end
102
+
103
+ it "doesn't encode utf8 characters" do
104
+ response = make_request(@job)
105
+ response['Content-Disposition'].should == 'filename="güng.txt"'
106
+ end
107
+
108
+ it "does encode them if the request is from IE" do
109
+ response = make_request(@job, 'HTTP_USER_AGENT' => "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; el-GR)")
110
+ response['Content-Disposition'].should == 'filename="g%C3%BCng.txt"'
111
+ end
112
+ end
113
+
97
114
  describe "logging" do
98
115
  it "logs successful requests" do
99
116
  Dragonfly.should_receive(:info).with("GET /something?great 200")
@@ -53,199 +53,12 @@ describe Dragonfly::Job do
53
53
  end
54
54
  end
55
55
 
56
- describe "fetch" do
57
- before(:each) do
58
- job.fetch!('some_uid')
59
- end
60
-
61
- it { job.steps.should match_steps([Dragonfly::Job::Fetch]) }
62
-
63
- it "should read from the app's datastore when applied" do
64
- app.datastore.should_receive(:read).with('some_uid').and_return ["", {}]
65
- job.apply
66
- end
67
-
68
- it "raises NotFound if the datastore returns nil" do
69
- app.datastore.should_receive(:read).and_return(nil)
70
- expect {
71
- job.apply
72
- }.to raise_error(Dragonfly::Job::Fetch::NotFound)
73
- end
74
- end
75
-
76
- describe "generate" do
77
- before :each do
78
- app.add_generator(:plasma){}
79
- end
80
-
81
- it "adds a step" do
82
- job.generate!(:plasma, 20)
83
- job.steps.should match_steps([Dragonfly::Job::Generate])
84
- end
85
-
86
- it "uses the generator when applied" do
87
- job.generate!(:plasma, 20)
88
- app.get_generator(:plasma).should_receive(:call).with(job.content, 20)
89
- job.apply
90
- end
91
-
92
- it "updates the url if method exists" do
93
- app.get_generator(:plasma).should_receive(:update_url).with(job.url_attributes, 20)
94
- job.generate!(:plasma, 20)
95
- end
96
- end
97
-
98
- describe "fetch_file" do
99
- before(:each) do
100
- job.fetch_file!(File.dirname(__FILE__) + '/../../samples/egg.png')
101
- end
102
-
103
- it { job.steps.should match_steps([Dragonfly::Job::FetchFile]) }
104
-
105
- it "should fetch the specified file when applied" do
106
- job.size.should == 62664
107
- end
108
-
109
- it "should set the url_attributes" do
110
- job.url_attributes.name.should == 'egg.png'
111
- end
112
-
113
- it "should set the name" do
114
- job.name.should == 'egg.png'
115
- end
116
- end
117
-
118
- describe "fetch_url" do
119
- before(:each) do
120
- stub_request(:get, %r{http://place\.com/.*}).to_return(:body => 'result!')
121
- end
122
-
123
- it "adds a step" do
124
- job.fetch_url!('some.url')
125
- job.steps.should match_steps([Dragonfly::Job::FetchUrl])
126
- end
127
-
128
- it "should fetch the specified url when applied" do
129
- job.fetch_url!('http://place.com')
130
- job.data.should == "result!"
131
- end
132
-
133
- it "should default to http" do
134
- job.fetch_url!('place.com')
135
- job.data.should == "result!"
136
- end
137
-
138
- it "should also work with https" do
139
- stub_request(:get, 'https://place.com').to_return(:body => 'secure result!')
140
- job.fetch_url!('https://place.com')
141
- job.data.should == "secure result!"
142
- end
143
-
144
- [
145
- "place.com",
146
- "http://place.com",
147
- "place.com/",
148
- "place.com/stuff/",
149
- "place.com/?things"
150
- ].each do |url|
151
- it "doesn't set the name if there isn't one, e.g. for #{url}" do
152
- job.fetch_url!(url)
153
- job.name.should be_nil
154
- end
155
-
156
- it "doesn't set the name url_attr if there isn't one, e.g. for #{url}" do
157
- job.fetch_url!(url)
158
- job.url_attributes.name.should be_nil
159
- end
160
- end
161
-
162
- [
163
- "place.com/dung.beetle",
164
- "http://place.com/dung.beetle",
165
- "place.com/stuff/dung.beetle",
166
- "place.com/dung.beetle?morethings"
167
- ].each do |url|
168
- it "sets the name if there is one, e.g. for #{url}" do
169
- job.fetch_url!(url)
170
- job.name.should == 'dung.beetle'
171
- end
172
-
173
- it "sets the name url_attr if there is one, e.g. for #{url}" do
174
- job.fetch_url!(url)
175
- job.url_attributes.name.should == 'dung.beetle'
176
- end
177
- end
178
-
179
- it "should raise an error if not found" do
180
- stub_request(:get, "notfound.com").to_return(:status => 404, :body => "BLAH")
181
- expect{
182
- job.fetch_url!('notfound.com').apply
183
- }.to raise_error(Dragonfly::Job::FetchUrl::ErrorResponse){|error|
184
- error.status.should == 404
185
- error.body.should == "BLAH"
186
- }
187
- end
188
-
189
- it "should raise an error if server error" do
190
- stub_request(:get, "error.com").to_return(:status => 500, :body => "BLAH")
191
- expect{
192
- job.fetch_url!('error.com').apply
193
- }.to raise_error(Dragonfly::Job::FetchUrl::ErrorResponse){|error|
194
- error.status.should == 500
195
- error.body.should == "BLAH"
196
- }
197
- end
198
-
199
- it "should follow redirects" do
200
- stub_request(:get, "redirectme.com").to_return(:status => 302, :headers => {'Location' => 'http://ok.com'})
201
- stub_request(:get, "ok.com").to_return(:body => "OK!")
202
- job.fetch_url('redirectme.com').data.should == 'OK!'
203
- end
204
-
205
- describe "data uris" do
206
- it "accepts standard base64 encoded data uris" do
207
- job.fetch_url!("data:text/plain;base64,aGVsbG8=\n")
208
- job.data.should == 'hello'
209
- job.mime_type.should == 'text/plain'
210
- job.ext.should == 'txt'
211
- end
212
-
213
- it "doesn't accept other data uris" do
214
- expect {
215
- job.fetch_url!("data:text/html;charset=utf-8,<stuff />").apply
216
- }.to raise_error(Dragonfly::Job::FetchUrl::CannotHandle)
217
- end
218
- end
219
- end
220
-
221
56
  describe "apply" do
222
57
  it "should return itself" do
223
58
  job.apply.should == job
224
59
  end
225
60
  end
226
61
 
227
- describe "process" do
228
- before :each do
229
- app.add_processor(:resize){}
230
- end
231
-
232
- it "adds a step" do
233
- job.process!(:resize, '20x30')
234
- job.steps.should match_steps([Dragonfly::Job::Process])
235
- end
236
-
237
- it "should use the processor when applied" do
238
- job.process!(:resize, '20x30')
239
- app.get_processor(:resize).should_receive(:call).with(job.content, '20x30')
240
- job.apply
241
- end
242
-
243
- it "should call update_url immediately with the url_attributes" do
244
- app.get_processor(:resize).should_receive(:update_url).with(job.url_attributes, '20x30')
245
- job.process!(:resize, '20x30')
246
- end
247
- end
248
-
249
62
  describe "analysis" do
250
63
  let (:job) { Dragonfly::Job.new(app, "HELLO") }
251
64
 
@@ -946,7 +946,7 @@ describe "models" do
946
946
  end
947
947
  end
948
948
 
949
- describe "changed?" do
949
+ describe "xxx_changed?" do
950
950
  before(:each) do
951
951
  @item_class = new_model_class('Item', :preview_image_uid) do
952
952
  dragonfly_accessor :preview_image
@@ -955,21 +955,36 @@ describe "models" do
955
955
  end
956
956
 
957
957
  it "should be changed when assigned" do
958
+ expect( @item.preview_image_changed? ).to be_false
958
959
  @item.preview_image = 'ggg'
959
- @item.preview_image.should be_changed
960
+ expect( @item.preview_image_changed? ).to be_true
960
961
  end
961
962
 
962
- it "should not be changed when saved" do
963
- @item.preview_image = 'ggg'
964
- @item.save!
965
- @item.preview_image.should_not be_changed
966
- end
963
+ describe "after saving" do
964
+ before do
965
+ @item.preview_image = 'ggg'
966
+ @item.save!
967
+ end
968
+
969
+ it "should not be changed" do
970
+ expect( @item.preview_image_changed? ).to be_false
971
+ end
972
+
973
+ it "should be changed when set to nil" do
974
+ @item.preview_image = nil
975
+ expect( @item.preview_image_changed? ).to be_true
976
+ end
977
+
978
+ it "should be changed when changed" do
979
+ @item.preview_image = "asdf"
980
+ expect( @item.preview_image_changed? ).to be_true
981
+ end
982
+
983
+ it "should not be changed when reloaded" do
984
+ item = @item_class.find(@item.id)
985
+ expect( @item.preview_image_changed? ).to be_false
986
+ end
967
987
 
968
- it "should not be changed when reloaded" do
969
- @item.preview_image = 'ggg'
970
- @item.save!
971
- item = @item_class.find(@item.id)
972
- item.preview_image.should_not be_changed
973
988
  end
974
989
  end
975
990
 
@@ -10,43 +10,84 @@ describe Dragonfly::RoutedEndpoint do
10
10
  Rack::MockRequest.env_for(url, opts)
11
11
  end
12
12
 
13
- before(:each) do
14
- @app = test_app
15
- @endpoint = Dragonfly::RoutedEndpoint.new(@app) {|params, app|
16
- app.fetch(params[:uid])
13
+ let (:app) { test_app }
14
+
15
+ describe "endpoint returning a job" do
16
+ let (:endpoint) {
17
+ Dragonfly::RoutedEndpoint.new(app) {|params, app|
18
+ app.fetch(params[:uid])
19
+ }
17
20
  }
18
- @uid = @app.store('wassup')
19
- end
20
21
 
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
22
+ before(:each) do
23
+ @uid = app.store('wassup')
24
+ end
25
+
26
+ it "should raise an error when there are no routing parameters" do
27
+ lambda{
28
+ endpoint.call(env_for('/blah'))
29
+ }.should raise_error(Dragonfly::RoutedEndpoint::NoRoutingParams)
30
+ end
31
+
32
+ {
33
+ 'Rails' => 'action_dispatch.request.path_parameters',
34
+ 'HTTP Router' => 'router.params',
35
+ 'Rack-Mount' => 'rack.routing_args',
36
+ 'Dragonfly' => 'dragonfly.params'
37
+ }.each do |name, key|
26
38
 
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|
39
+ it "should work with #{name} routing args" do
40
+ response = response_for endpoint.call(env_for('/blah', key => {:uid => @uid}))
41
+ response.body.should == 'wassup'
42
+ end
34
43
 
35
- it "should work with #{name} routing args" do
36
- response = response_for @endpoint.call(env_for('/blah', key => {:uid => @uid}))
44
+ end
45
+
46
+ it "should merge with query parameters" do
47
+ env = Rack::MockRequest.env_for("/big/buns?uid=#{@uid}", 'dragonfly.params' => {:something => 'else'})
48
+ response = response_for endpoint.call(env)
37
49
  response.body.should == 'wassup'
38
50
  end
39
51
 
52
+ it "should have nice inspect output" do
53
+ endpoint.inspect.should =~ /<Dragonfly::RoutedEndpoint for app :default >/
54
+ end
40
55
  end
41
56
 
42
- it "should merge with query parameters" do
43
- env = Rack::MockRequest.env_for("/big/buns?uid=#{@uid}", 'dragonfly.params' => {:something => 'else'})
44
- response = response_for @endpoint.call(env)
45
- response.body.should == 'wassup'
46
- end
57
+ describe "endpoint returning other things" do
58
+ let (:model_class) {
59
+ Class.new do
60
+ extend Dragonfly::Model
61
+ dragonfly_accessor :image
62
+ attr_accessor :image_uid
63
+ end
64
+ }
65
+ let (:model) {
66
+ model_class.new
67
+ }
68
+ let (:endpoint) {
69
+ Dragonfly::RoutedEndpoint.new(app) {|params, app|
70
+ model.image
71
+ }
72
+ }
73
+
74
+ it "acts like the job one" do
75
+ model.image = "wassup"
76
+ response = response_for endpoint.call(env_for('/blah', 'dragonfly.params' => {}))
77
+ response.body.should == 'wassup'
78
+ end
79
+
80
+ it "returns 404 if nil is returned from the endpoint" do
81
+ endpoint = Dragonfly::RoutedEndpoint.new(app) { nil }
82
+ response = response_for endpoint.call(env_for('/blah', 'dragonfly.params' => {}))
83
+ response.status.should == 404
84
+ end
47
85
 
48
- it "should have nice inspect output" do
49
- @endpoint.inspect.should =~ /<Dragonfly::RoutedEndpoint for app :default >/
50
- end
86
+ it "returns 500 if something else is returned from the endpoint" do
87
+ endpoint = Dragonfly::RoutedEndpoint.new(app) { "ASDF" }
88
+ response = response_for endpoint.call(env_for('/blah', 'dragonfly.params' => {}))
89
+ response.status.should == 500
90
+ end
91
+ end
51
92
 
52
93
  end