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,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Array do
4
+
5
+ describe "to_dragonfly_unique_s" do
6
+ it "should concatenate the to_s's of each of the elements" do
7
+ [:a, true, 2, 5.2, "hello"].to_dragonfly_unique_s.should == 'atrue25.2hello'
8
+ end
9
+
10
+ it "should nest arrays" do
11
+ [:a, [:b, :c], :d].to_dragonfly_unique_s.should == 'abcd'
12
+ end
13
+
14
+ it "should be empty if empty" do
15
+ [].to_dragonfly_unique_s.should == ''
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hash do
4
+
5
+ describe "to_dragonfly_unique_s" do
6
+ it "should concatenate the to_s's of each of the elements, sorted alphabetically" do
7
+ {'z' => nil, :a => 4, false => 'ice', 5 => 6.2}.to_dragonfly_unique_s.should == '56.2a4falseicez'
8
+ end
9
+
10
+ it "should nest correctly" do
11
+ {:m => 1, :a => {:c => 2, :b => 3}, :z => 4}.to_dragonfly_unique_s.should == 'ab3c2m1z4'
12
+ end
13
+
14
+ it "should be empty if empty" do
15
+ {}.to_dragonfly_unique_s.should == ''
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+
5
+ describe "to_method_name" do
6
+ if RUBY_VERSION =~ /^1.8/
7
+ it "should return a string" do
8
+ 'hello'.to_method_name.should == 'hello'
9
+ end
10
+ else
11
+ it "should return a symbol" do
12
+ 'hello'.to_method_name.should == :hello
13
+ end
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Symbol do
4
+
5
+ describe "to_method_name" do
6
+ if RUBY_VERSION =~ /^1.8/
7
+ it "should return a string" do
8
+ :hello.to_method_name.should == 'hello'
9
+ end
10
+ else
11
+ it "should return a symbol" do
12
+ :hello.to_method_name.should == :hello
13
+ end
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,76 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require File.dirname(__FILE__) + '/shared_data_store_examples'
4
+ require 'net/http'
5
+
6
+ describe Dragonfly::DataStorage::CouchDataStore do
7
+
8
+ before(:each) do
9
+ WebMock.allow_net_connect!
10
+ @data_store = Dragonfly::DataStorage::CouchDataStore.new(
11
+ :host => "localhost",
12
+ :port => "5984",
13
+ :username => "",
14
+ :password => "",
15
+ :database => "dragonfly_test"
16
+ )
17
+ begin
18
+ @data_store.db.get('ping')
19
+ rescue Errno::ECONNREFUSED => e
20
+ pending "You need to start CouchDB on localhost:5984 to test the CouchDataStore"
21
+ rescue RestClient::ResourceNotFound
22
+ end
23
+
24
+ end
25
+
26
+ it_should_behave_like 'data_store'
27
+
28
+ describe "destroy" do
29
+ before(:each) do
30
+ @temp_object = Dragonfly::TempObject.new('gollum')
31
+ end
32
+
33
+ it "should raise an error if the data doesn't exist on destroy" do
34
+ uid = @data_store.store(@temp_object)
35
+ @data_store.destroy(uid)
36
+ lambda{
37
+ @data_store.destroy(uid)
38
+ }.should raise_error(Dragonfly::DataStorage::DataNotFound)
39
+ end
40
+ end
41
+
42
+ describe "serving from couchdb" do
43
+
44
+ def get_content(uid, name)
45
+ Net::HTTP.start('localhost', 5984) {|http|
46
+ http.get("/dragonfly_test/#{uid}/#{name}")
47
+ }
48
+ end
49
+
50
+ before(:each) do
51
+ @temp_object = Dragonfly::TempObject.new('testingyo')
52
+ end
53
+
54
+ it "should use the fallback by default" do
55
+ uid = @data_store.store(@temp_object)
56
+ response = get_content(uid, 'file')
57
+ response.body.should == 'testingyo'
58
+ response['Content-Type'].should == 'application/octet-stream'
59
+ end
60
+
61
+ it "should allow setting on store with 'content_type'" do
62
+ uid = @data_store.store(@temp_object, :content_type => 'text/plain')
63
+ response = get_content(uid, 'file')
64
+ response.body.should == 'testingyo'
65
+ response['Content-Type'].should == 'text/plain'
66
+ end
67
+
68
+ it "should allow setting on store with 'mime_type'" do
69
+ uid = @data_store.store(@temp_object, :mime_type => 'text/plain-yo')
70
+ response = get_content(uid, 'file')
71
+ response.body.should == 'testingyo'
72
+ response['Content-Type'].should == 'text/plain-yo'
73
+ end
74
+ end
75
+
76
+ end
@@ -0,0 +1,296 @@
1
+ require 'spec_helper'
2
+ require File.dirname(__FILE__) + '/shared_data_store_examples'
3
+
4
+ describe Dragonfly::DataStorage::FileDataStore do
5
+
6
+ def touch_file(filename)
7
+ FileUtils.mkdir_p(File.dirname(filename))
8
+ FileUtils.touch(filename)
9
+ end
10
+
11
+ before(:each) do
12
+ @data_store = Dragonfly::DataStorage::FileDataStore.new
13
+ @data_store.root_path = '/var/tmp/dragonfly_test'
14
+ end
15
+
16
+ after(:each) do
17
+ # Clean up created files
18
+ FileUtils.rm_rf("#{@data_store.root_path}")
19
+ end
20
+
21
+ it_should_behave_like 'data_store'
22
+
23
+ before(:each) do
24
+ @temp_object = Dragonfly::TempObject.new('goobydoo')
25
+ end
26
+
27
+ describe "store" do
28
+
29
+ def it_should_write_to_file(storage_path, temp_object)
30
+ temp_object.should_receive(:to_file).with(storage_path).and_return(mock('file', :close => nil))
31
+ end
32
+
33
+ before(:each) do
34
+ # Set 'now' to a date in the past
35
+ Time.stub!(:now).and_return Time.mktime(1984,"may",4,14,28,1)
36
+ @file_pattern_prefix_without_root = '1984/05/04/14_28_01_0_'
37
+ @file_pattern_prefix = "#{@data_store.root_path}/#{@file_pattern_prefix_without_root}"
38
+ end
39
+
40
+ it "should store the file in a folder based on date, with default filename" do
41
+ it_should_write_to_file("#{@file_pattern_prefix}file", @temp_object)
42
+ @data_store.store(@temp_object)
43
+ end
44
+
45
+ it "should use the temp_object original filename if it exists" do
46
+ @temp_object.should_receive(:original_filename).at_least(:once).and_return('hello.there')
47
+ it_should_write_to_file("#{@file_pattern_prefix}hello.there", @temp_object)
48
+ @data_store.store(@temp_object)
49
+ end
50
+
51
+ it "should use the meta name if it exists" do
52
+ it_should_write_to_file("#{@file_pattern_prefix}damp.squib", @temp_object)
53
+ @data_store.store(@temp_object, :meta => {:name => 'damp.squib'})
54
+ end
55
+
56
+ it "should prefer the meta name to the original filename" do
57
+ @temp_object.stub!(:original_filename).and_return('hello.there')
58
+ it_should_write_to_file("#{@file_pattern_prefix}damp.squib", @temp_object)
59
+ @data_store.store(@temp_object, :meta => {:name => 'damp.squib'})
60
+ end
61
+
62
+ it "should get rid of funny characters in the temp_object original filename" do
63
+ @temp_object.should_receive(:original_filename).at_least(:once).and_return('A Picture with many spaces in its name (at 20:00 pm).png')
64
+ it_should_write_to_file("#{@file_pattern_prefix}A_Picture_with_many_spaces_in_its_name_at_20_00_pm_.png", @temp_object)
65
+ @data_store.store(@temp_object)
66
+ end
67
+
68
+ describe "when the filename already exists" do
69
+
70
+ it "should use a different filename" do
71
+ touch_file("#{@file_pattern_prefix}file")
72
+ @data_store.should_receive(:disambiguate).with("#{@file_pattern_prefix}file").and_return("#{@file_pattern_prefix}file_2")
73
+ it_should_write_to_file("#{@file_pattern_prefix}file_2", @temp_object)
74
+ @data_store.store(@temp_object)
75
+ end
76
+
77
+ it "should use a different filename taking into account the name and ext" do
78
+ @temp_object.should_receive(:original_filename).at_least(:once).and_return('hello.png')
79
+ touch_file("#{@file_pattern_prefix}hello.png")
80
+ @data_store.should_receive(:disambiguate).with("#{@file_pattern_prefix}hello.png").and_return("#{@file_pattern_prefix}blah.png")
81
+ @data_store.store(@temp_object)
82
+ end
83
+
84
+ it "should keep trying until it finds a free filename" do
85
+ touch_file("#{@file_pattern_prefix}file")
86
+ touch_file("#{@file_pattern_prefix}file_2")
87
+ @data_store.should_receive(:disambiguate).with("#{@file_pattern_prefix}file").and_return("#{@file_pattern_prefix}file_2")
88
+ @data_store.should_receive(:disambiguate).with("#{@file_pattern_prefix}file_2").and_return("#{@file_pattern_prefix}file_3")
89
+ it_should_write_to_file("#{@file_pattern_prefix}file_3", @temp_object)
90
+ @data_store.store(@temp_object)
91
+ end
92
+
93
+ describe "specifying the uid" do
94
+ it "should allow for specifying the path to use" do
95
+ it_should_write_to_file("#{@data_store.root_path}/hello/there/mate.png", @temp_object)
96
+ @data_store.store(@temp_object, :path => 'hello/there/mate.png')
97
+ end
98
+ it "should correctly disambiguate if the file exists" do
99
+ touch_file("#{@data_store.root_path}/hello/there/mate.png")
100
+ @data_store.should_receive(:disambiguate).with("#{@data_store.root_path}/hello/there/mate.png").and_return("#{@data_store.root_path}/hello/there/mate_2.png")
101
+ it_should_write_to_file("#{@data_store.root_path}/hello/there/mate_2.png", @temp_object)
102
+ @data_store.store(@temp_object, :path => 'hello/there/mate.png')
103
+ end
104
+ end
105
+
106
+ end
107
+
108
+ describe "return value" do
109
+
110
+ it "should return the filepath without the root of the stored file when a file name is not provided" do
111
+ @data_store.store(@temp_object).should == "#{@file_pattern_prefix_without_root}file"
112
+ end
113
+
114
+ it "should return the filepath without the root of the stored file when a file name is provided" do
115
+ @temp_object.should_receive(:original_filename).at_least(:once).and_return('hello.you.png')
116
+ @data_store.store(@temp_object).should == "#{@file_pattern_prefix_without_root}hello.you.png"
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+
123
+ describe "disambiguate" do
124
+ it "should add a suffix" do
125
+ @data_store.disambiguate('/some/file').should =~ %r{^/some/file_\w+$}
126
+ end
127
+ it "should add a suffix to the basename" do
128
+ @data_store.disambiguate('/some/file.png').should =~ %r{^/some/file_\w+\.png$}
129
+ end
130
+ it "should be random(-ish)" do
131
+ @data_store.disambiguate('/some/file').should_not == @data_store.disambiguate('/some/file')
132
+ end
133
+ end
134
+
135
+ describe "errors" do
136
+
137
+ it "should raise an error if it can't create a directory" do
138
+ FileUtils.should_receive(:mkdir_p).and_raise(Errno::EACCES)
139
+ lambda{ @data_store.store(@temp_object) }.should raise_error(Dragonfly::DataStorage::UnableToStore)
140
+ end
141
+
142
+ it "should raise an error if it can't create a file" do
143
+ @temp_object.should_receive(:to_file).and_raise(Errno::EACCES)
144
+ lambda{ @data_store.store(@temp_object) }.should raise_error(Dragonfly::DataStorage::UnableToStore)
145
+ end
146
+
147
+ end
148
+
149
+ describe "retrieve" do
150
+ it "should return a pathname" do
151
+ uid = @data_store.store(@temp_object)
152
+ pathname, meta = @data_store.retrieve(uid)
153
+ pathname.should be_a(Pathname)
154
+ end
155
+ it "should be able to retrieve any file, stored or not (and without meta data)" do
156
+ FileUtils.mkdir_p("#{@data_store.root_path}/jelly_beans/are")
157
+ File.open("#{@data_store.root_path}/jelly_beans/are/good", 'w'){|f| f.write('hey dog') }
158
+ pathname, meta = @data_store.retrieve("jelly_beans/are/good")
159
+ pathname.read.should == 'hey dog'
160
+ meta.should == {}
161
+ end
162
+ it "should work even if meta is stored in old .extra file" do
163
+ uid = @data_store.store(@temp_object, :meta => {:dog => 'food'})
164
+ FileUtils.mv("#{@data_store.root_path}/#{uid}.meta", "#{@data_store.root_path}/#{uid}.extra")
165
+ pathname, meta = @data_store.retrieve(uid)
166
+ meta.should == {:dog => 'food'}
167
+ end
168
+ end
169
+
170
+ describe "destroying" do
171
+
172
+ it "should prune empty directories when destroying" do
173
+ uid = @data_store.store(@temp_object)
174
+ @data_store.destroy(uid)
175
+ @data_store.root_path.should be_an_empty_directory
176
+ end
177
+
178
+ it "should raise an error if the data doesn't exist on destroy" do
179
+ uid = @data_store.store(@temp_object)
180
+ @data_store.destroy(uid)
181
+ lambda{
182
+ @data_store.destroy(uid)
183
+ }.should raise_error(Dragonfly::DataStorage::DataNotFound)
184
+ end
185
+
186
+ it "should also destroy old .extra files" do
187
+ uid = @data_store.store(@temp_object)
188
+ FileUtils.cp("#{@data_store.root_path}/#{uid}.meta", "#{@data_store.root_path}/#{uid}.extra")
189
+ @data_store.destroy(uid)
190
+ File.exist?("#{@data_store.root_path}/#{uid}").should be_false
191
+ File.exist?("#{@data_store.root_path}/#{uid}.meta").should be_false
192
+ File.exist?("#{@data_store.root_path}/#{uid}.extra").should be_false
193
+ end
194
+
195
+ end
196
+
197
+ describe "relative paths" do
198
+ let(:store) { Dragonfly::DataStorage::FileDataStore.new }
199
+ let(:relative_path) { "2011/02/11/picture.jpg" }
200
+ let(:absolute_path) { "#{root_path}#{relative_path}" }
201
+ let(:root_path) { "/path/to/file/" }
202
+
203
+ before do
204
+ store.root_path = root_path
205
+ end
206
+
207
+ subject { store.send :relative, absolute_path }
208
+
209
+ it { should == relative_path }
210
+
211
+ context "where root path contains spaces" do
212
+ let(:root_path) { "/path/to/file name/" }
213
+ it { should == relative_path }
214
+ end
215
+ context "where root path contains special chars" do
216
+ let(:root_path) { "/path/to/file name (Special backup directory)/" }
217
+ it { should == relative_path }
218
+ end
219
+ end
220
+
221
+ describe "turning meta off" do
222
+ before(:each) do
223
+ @data_store.store_meta = false
224
+ end
225
+
226
+ it "should not write a meta file" do
227
+ uid = @data_store.store(@temp_object, :meta => {:bitrate => '35', :name => 'danny.boy'})
228
+ path = File.join(@data_store.root_path, uid) + '.meta'
229
+ File.exist?(path).should be_false
230
+ end
231
+
232
+ it "should return an empty hash on retrieve" do
233
+ uid = @data_store.store(@temp_object, :meta => {:bitrate => '35', :name => 'danny.boy'})
234
+ obj, meta = @data_store.retrieve(uid)
235
+ meta.should == {}
236
+ end
237
+
238
+ it "should still destroy the meta file if it exists" do
239
+ @data_store.store_meta = true
240
+ uid = @data_store.store(@temp_object)
241
+ @data_store.store_meta = false
242
+ @data_store.destroy(uid)
243
+ @data_store.root_path.should be_an_empty_directory
244
+ end
245
+
246
+ it "should still destroy properly if meta is on but the meta file doesn't exist" do
247
+ uid = @data_store.store(@temp_object)
248
+ @data_store.store_meta = true
249
+ @data_store.destroy(uid)
250
+ @data_store.root_path.should be_an_empty_directory
251
+ end
252
+ end
253
+
254
+ describe "urls for serving directly" do
255
+ before(:each) do
256
+ @uid = 'some/path/to/file.png'
257
+ @data_store.root_path = '/var/tmp/eggs'
258
+ end
259
+
260
+ it "should raise an error if called without configuring" do
261
+ expect{
262
+ @data_store.url_for(@uid)
263
+ }.to raise_error(Dragonfly::Configurable::NotConfigured)
264
+ end
265
+
266
+ it "should work as expected when the the server root is above the root path" do
267
+ @data_store.server_root = '/var/tmp'
268
+ @data_store.url_for(@uid).should == '/eggs/some/path/to/file.png'
269
+ end
270
+
271
+ it "should work as expected when the the server root is the root path" do
272
+ @data_store.server_root = '/var/tmp/eggs'
273
+ @data_store.url_for(@uid).should == '/some/path/to/file.png'
274
+ end
275
+
276
+ it "should work as expected when the the server root is below the root path" do
277
+ @data_store.server_root = '/var/tmp/eggs/some/path'
278
+ @data_store.url_for(@uid).should == '/to/file.png'
279
+ end
280
+
281
+ it "should raise an error when the server root doesn't coincide with the root path" do
282
+ @data_store.server_root = '/var/blimey/eggs'
283
+ expect{
284
+ @data_store.url_for(@uid)
285
+ }.to raise_error(Dragonfly::DataStorage::FileDataStore::UnableToFormUrl)
286
+ end
287
+
288
+ it "should raise an error when the server root doesn't coincide with the uid" do
289
+ @data_store.server_root = '/var/tmp/eggs/some/gooney'
290
+ expect{
291
+ @data_store.url_for(@uid)
292
+ }.to raise_error(Dragonfly::DataStorage::FileDataStore::UnableToFormUrl)
293
+ end
294
+ end
295
+
296
+ end