Skip to content

Instantly share code, notes, and snippets.

@jeshuaborges
Last active December 12, 2015 05:08
Show Gist options
  • Save jeshuaborges/4719341 to your computer and use it in GitHub Desktop.
Save jeshuaborges/4719341 to your computer and use it in GitHub Desktop.
require 'tempfile'
class UploadStore
class File
attr_reader :file
# Public:
#
# file - Fog file.
def initialize(file)
@file = file
end
# Internal: Wraps the processing of the upload file. Ensures that upload is
# properly cleaned up after processing.
#
# Returns a block result.
def process(&blk)
result = tempfile(&blk)
# Should we add destroy to an ensure block? Im not sure if it makes sense
# to delete failed files.
file.destroy
result
end
def name_parts
parts = file.key.split('/').last.split('.')
# Re-introduce the '.' for the file extension
parts << ".#{parts.pop}"
end
def tempfile
tmp = Tempfile.new(name_parts)
tmp.binmode
begin
tmp.write(file.body)
tmp.rewind
yield tmp
ensure
tmp.close
tmp.unlink
end
end
def destroy
file.destroy
end
end
end
require 'spec_helper'
describe UploadStore::File do
before do
# This is a lot of work to set up but its very worth it to ensure that
# this core processing logic is functioning as expected.
connection = Fog::Storage.new({
provider: 'Local',
local_root: Rails.root.join('tmp'),
endpoint: Rails.root.join('tmp')
})
directory = connection.directories.create(key: 'fog-test')
@fog_file = directory.files.create(
:key => 'world-bar.jpeg',
:body => File.open(Rails.root.join('spec/fixtures/world-bar.jpeg')),
:public => true
)
@upload_file = UploadStore::File.new(@fog_file)
end
it 'uses the file extension with the tempfile' do
@upload_file.process do |file|
expect(file.path).to end_with('.jpeg')
end
end
end
require 'unit_helper'
require 'upload_file'
# TODO: Stub Tempfile and remove the file system from the unit tests.
describe UploadStore::File do
let(:decorated) { double(:file, destroy: true, body: 'body', key: 'key.ext') }
let(:file) { UploadStore::File.new(decorated) }
it 'splits name parts to preserve the file extension' do
expect(file.name_parts).to eql(['key', '.ext'])
end
it 'process deletes the uploaded file' do
decorated.should_receive(:destroy)
file.process {|file| }
end
it 'process returns the value of the block' do
val = file.process {|file| 'block_value' }
expect(val).to eql('block_value')
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment