diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 769f17ed7..c8d131d0f 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -3,6 +3,9 @@ class Attachment < ActiveRecord::Base + #----- Constants ---------------------------------------------------------------- + UNKNOWN_MIME_TYPE = 'application/octet-stream' + #----- Macros ---------------------------------------------------------------- is_archivable @@ -10,10 +13,15 @@ class Attachment < ActiveRecord::Base uses_soft_delete is_userstamped is_versioned - attr_accessor :temp_file - #----- Callbacks ------------------------------------------------------------- + # Rails 3 uses a new ActionDispatch::Http::UploadedFile. This holds that during the file processing. + attr_accessor :uploaded_file + + # This exists for backwards compatibility + alias_method :temp_file, :uploaded_file + alias_method :temp_file=, :uploaded_file= + #----- Callbacks ------------------------------------------------------------- before_validation :make_dirty_if_temp_file before_validation :prepend_file_path_with_slash before_validation :extract_file_extension_from_file_name @@ -24,7 +32,8 @@ class Attachment < ActiveRecord::Base after_save :write_temp_file_to_storage_location after_save :clear_ivars - + + #----- Associations ---------------------------------------------------------- has_one :section_node, :as => :node @@ -83,6 +92,11 @@ def extract_file_extension_from_file_name def extract_file_type_from_temp_file unless temp_file.blank? self.file_type = temp_file.content_type + + # Some + if self.file_type == nil + self.file_type = UNKNOWN_MIME_TYPE + end end end @@ -114,11 +128,14 @@ def process_section def write_temp_file_to_storage_location unless temp_file.blank? + actual_temp_file = temp_file.tempfile + + Rails.logger.warn "I want to write out #{temp_file.tempfile}" FileUtils.mkdir_p File.dirname(full_file_location) - if temp_file.local_path - FileUtils.copy temp_file.local_path, full_file_location + if actual_temp_file.path + FileUtils.copy actual_temp_file.path, full_file_location else - open(full_file_location, 'w') {|f| f << temp_file.read } + open(full_file_location, 'w') {|f| f << actual_temp_file.read } end if Cms.attachment_file_permission diff --git a/app/models/file_block.rb b/app/models/file_block.rb index 40fb621ca..9c7e08eca 100644 --- a/app/models/file_block.rb +++ b/app/models/file_block.rb @@ -2,6 +2,16 @@ class FileBlock < AbstractFileBlock acts_as_content_block :belongs_to_attachment => true, :taggable => true + before_validation :report! + + def report! + logger.warn "attachment_file = #{attachment_file}" + logger.warn "attachment_file.class = #{attachment_file.class}" +# logger.warn "temp_file = #{temp_file}" +# logger.warn "temp_file.class = #{temp_file.class}" + end + + def set_attachment_file_path if @attachment_file_path && @attachment_file_path != attachment.file_path attachment.file_path = @attachment_file_path diff --git a/lib/cms/behaviors/attaching.rb b/lib/cms/behaviors/attaching.rb index a8e95c29a..8fcba8b5a 100644 --- a/lib/cms/behaviors/attaching.rb +++ b/lib/cms/behaviors/attaching.rb @@ -84,6 +84,7 @@ def attachment_section=(section) end def process_attachment + Rails.logger.warn "Processing attachment (#{attachment_file})" if attachment.nil? && attachment_file.blank? unless attachment_file_path.blank? errors.add(:attachment_file, "You must upload a file") @@ -95,7 +96,9 @@ def process_attachment end else build_attachment if attachment.nil? - attachment.temp_file = attachment_file + attachment.temp_file = attachment_file + Rails.logger.warn "After attachment (#{attachment.temp_file})" + set_attachment_file_path if attachment.file_path.blank? errors.add(:attachment_file_path, "File Name is required for attachment") diff --git a/test/functional/cms/content_controller_test.rb b/test/functional/cms/content_controller_test.rb index 13756259a..c3193dab7 100644 --- a/test/functional/cms/content_controller_test.rb +++ b/test/functional/cms/content_controller_test.rb @@ -71,6 +71,7 @@ def test_show_file get :show, :path => "test.txt" assert_response :success + puts @response.body assert_equal "text/plain", @response.content_type assert_equal "This is a test", streaming_file_contents end diff --git a/test/mock_file.rb b/test/mock_file.rb index 1b4d83084..1c3eab5ef 100644 --- a/test/mock_file.rb +++ b/test/mock_file.rb @@ -14,4 +14,20 @@ def self.new_file(file_name='foo.jpg', content_type="image/jpeg") def self.activate_logging ActiveRecord::Base.logger = Logger.new(STDOUT) end -end \ No newline at end of file +end + +module Extensions + module Rack + module Test + # Extensions to make Rack::Test::UploadedFile function like ActionDispatch::Http::UploadedFile during unit/functional tests. + module UploadedFile + + # Attachment relies on this being there + def tempfile + @tempfile + end + end + end + end +end +Rack::Test::UploadedFile.send(:include, Extensions::Rack::Test::UploadedFile) \ No newline at end of file diff --git a/test/unit/models/attachment_test.rb b/test/unit/models/attachment_test.rb index 22258c22a..f3e1356bd 100644 --- a/test/unit/models/attachment_test.rb +++ b/test/unit/models/attachment_test.rb @@ -72,6 +72,15 @@ def test_find_live_by_file_path assert !attachment.live?, "Attachment should not be live" assert_equal attachment.as_of_version(2), Attachment.find_live_by_file_path("/foo.txt") end + + test "If an uploaded file has no detectable content type (i.e. markdown) then assign it the 'unknown' type" do + mock_file = mock() + mock_file.expects(:content_type).returns(nil) + atk = Attachment.new(:temp_file => mock_file) + atk.extract_file_type_from_temp_file + + assert_equal Attachment::UNKNOWN_MIME_TYPE, atk.file_type + end end class Attachment::SectionTest < ActiveSupport::TestCase diff --git a/test/unit/models/file_block_test.rb b/test/unit/models/file_block_test.rb index cb5c36438..731f3860c 100644 --- a/test/unit/models/file_block_test.rb +++ b/test/unit/models/file_block_test.rb @@ -3,9 +3,8 @@ class FileBlockTest < ActiveSupport::TestCase def setup #@file is a mock of the object that Rails wraps file uploads in - @file = file_upload_object(:original_filename => "version1.txt", - :content_type => "text/plain") - @file_block = Factory.build(:file_block, :attachment_file => @file, :attachment_section => root_section, :attachment_file_path => "/test.jpg", :publish_on_save => true) + @uploaded_file = file_upload_object(:original_filename => "version1.txt", :content_type => "text/plain") + @file_block = Factory.build(:file_block, :attachment_file => @uploaded_file, :attachment_section => root_section, :attachment_file_path => "/test.jpg", :publish_on_save => true) end test "Saving should also save attachment." do