file_column_with_s3 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +69 -0
- data/README +54 -0
- data/Rakefile +40 -0
- data/lib/file_column.rb +734 -0
- data/lib/file_column/attachement_store.rb +93 -0
- data/lib/file_column_helper.rb +150 -0
- data/lib/file_compat.rb +28 -0
- data/lib/magick_file_column.rb +265 -0
- data/lib/rails_file_column.rb +19 -0
- data/lib/test_case.rb +124 -0
- data/lib/validations.rb +112 -0
- data/s3_env.example +5 -0
- data/test/abstract_unit.rb +66 -0
- data/test/attachement_store_test.rb +96 -0
- data/test/connection.rb +11 -0
- data/test/file_column_helper_test.rb +98 -0
- data/test/file_column_test.rb +652 -0
- data/test/fixtures/entry.rb +28 -0
- data/test/fixtures/invalid-image.jpg +1 -0
- data/test/fixtures/kerb.jpg +0 -0
- data/test/fixtures/mysql.sql +25 -0
- data/test/fixtures/schema.rb +10 -0
- data/test/fixtures/skanthak.png +0 -0
- data/test/magick_test.rb +391 -0
- data/test/magick_view_only_test.rb +21 -0
- metadata +132 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
# require this file from your "config/environment.rb" (after rails has been loaded)
|
2
|
+
# to integrate the file_column extension into rails.
|
3
|
+
|
4
|
+
require 'file_column'
|
5
|
+
require 'file_column_helper'
|
6
|
+
|
7
|
+
|
8
|
+
module ActiveRecord # :nodoc:
|
9
|
+
class Base # :nodoc:
|
10
|
+
# make file_column method available in all active record decendants
|
11
|
+
include FileColumn
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ActionView # :nodoc:
|
16
|
+
class Base # :nodoc:
|
17
|
+
include FileColumnHelper
|
18
|
+
end
|
19
|
+
end
|
data/lib/test_case.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
# Add the methods +upload+, the <tt>setup_file_fixtures</tt> and
|
4
|
+
# <tt>teardown_file_fixtures</tt> to the class Test::Unit::TestCase.
|
5
|
+
class Test::Unit::TestCase
|
6
|
+
# Returns a +Tempfile+ object as it would have been generated on file upload.
|
7
|
+
# Use this method to create the parameters when emulating form posts with
|
8
|
+
# file fields.
|
9
|
+
#
|
10
|
+
# === Example:
|
11
|
+
#
|
12
|
+
# def test_file_column_post
|
13
|
+
# entry = { :title => 'foo', :file => upload('/tmp/foo.txt')}
|
14
|
+
# post :upload, :entry => entry
|
15
|
+
#
|
16
|
+
# # ...
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# === Parameters
|
20
|
+
#
|
21
|
+
# * <tt>path</tt> The path to the file to upload.
|
22
|
+
# * <tt>content_type</tt> The MIME type of the file. If it is <tt>:guess</tt>,
|
23
|
+
# the method will try to guess it.
|
24
|
+
def upload(path, content_type=:guess, type=:tempfile)
|
25
|
+
if content_type == :guess
|
26
|
+
case path
|
27
|
+
when /\.jpg$/ then content_type = "image/jpeg"
|
28
|
+
when /\.png$/ then content_type = "image/png"
|
29
|
+
else content_type = nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
uploaded_file(path, content_type, File.basename(path), type)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Copies the fixture files from "RAILS_ROOT/test/fixtures/file_column" into
|
36
|
+
# the temporary storage directory used for testing
|
37
|
+
# ("RAILS_ROOT/test/tmp/file_column"). Call this method in your
|
38
|
+
# <tt>setup</tt> methods to get the file fixtures (images, for example) into
|
39
|
+
# the directory used by file_column in testing.
|
40
|
+
#
|
41
|
+
# Note that the files and directories in the "fixtures/file_column" directory
|
42
|
+
# must have the same structure as you would expect in your "/public" directory
|
43
|
+
# after uploading with FileColumn.
|
44
|
+
#
|
45
|
+
# For example, the directory structure could look like this:
|
46
|
+
#
|
47
|
+
# test/fixtures/file_column/
|
48
|
+
# `-- container
|
49
|
+
# |-- first_image
|
50
|
+
# | |-- 1
|
51
|
+
# | | `-- image1.jpg
|
52
|
+
# | `-- tmp
|
53
|
+
# `-- second_image
|
54
|
+
# |-- 1
|
55
|
+
# | `-- image2.jpg
|
56
|
+
# `-- tmp
|
57
|
+
#
|
58
|
+
# Your fixture file for this one "container" class fixture could look like this:
|
59
|
+
#
|
60
|
+
# first:
|
61
|
+
# id: 1
|
62
|
+
# first_image: image1.jpg
|
63
|
+
# second_image: image1.jpg
|
64
|
+
#
|
65
|
+
# A usage example:
|
66
|
+
#
|
67
|
+
# def setup
|
68
|
+
# setup_fixture_files
|
69
|
+
#
|
70
|
+
# # ...
|
71
|
+
# end
|
72
|
+
def setup_fixture_files
|
73
|
+
tmp_path = File.join(RAILS_ROOT, "test", "tmp", "file_column")
|
74
|
+
file_fixtures = Dir.glob File.join(RAILS_ROOT, "test", "fixtures", "file_column", "*")
|
75
|
+
|
76
|
+
FileUtils.mkdir_p tmp_path unless File.exists?(tmp_path)
|
77
|
+
FileUtils.cp_r file_fixtures, tmp_path
|
78
|
+
end
|
79
|
+
|
80
|
+
# Removes the directory "RAILS_ROOT/test/tmp/file_column/" so the files
|
81
|
+
# copied on test startup are removed. Call this in your unit test's +teardown+
|
82
|
+
# method.
|
83
|
+
#
|
84
|
+
# A usage example:
|
85
|
+
#
|
86
|
+
# def teardown
|
87
|
+
# teardown_fixture_files
|
88
|
+
#
|
89
|
+
# # ...
|
90
|
+
# end
|
91
|
+
def teardown_fixture_files
|
92
|
+
FileUtils.rm_rf File.join(RAILS_ROOT, "test", "tmp", "file_column")
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def uploaded_file(path, content_type, filename, type=:tempfile) # :nodoc:
|
98
|
+
if type == :tempfile
|
99
|
+
t = Tempfile.new(File.basename(filename))
|
100
|
+
FileUtils.copy_file(path, t.path)
|
101
|
+
else
|
102
|
+
if path
|
103
|
+
t = StringIO.new(IO.read(path))
|
104
|
+
else
|
105
|
+
t = StringIO.new
|
106
|
+
end
|
107
|
+
end
|
108
|
+
(class << t; self; end).class_eval do
|
109
|
+
alias local_path path if type == :tempfile
|
110
|
+
define_method(:local_path) { "" } if type == :stringio
|
111
|
+
define_method(:original_filename) {filename}
|
112
|
+
define_method(:content_type) {content_type}
|
113
|
+
end
|
114
|
+
return t
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# If we are running in the "test" environment, we overwrite the default
|
119
|
+
# settings for FileColumn so that files are not uploaded into "/public/"
|
120
|
+
# in tests but rather into the directory "/test/tmp/file_column".
|
121
|
+
if RAILS_ENV == "test"
|
122
|
+
FileColumn::ClassMethods::DEFAULT_OPTIONS[:root_path] =
|
123
|
+
File.join(RAILS_ROOT, "test", "tmp", "file_column")
|
124
|
+
end
|
data/lib/validations.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
module FileColumn
|
2
|
+
module Validations #:nodoc:
|
3
|
+
|
4
|
+
def self.append_features(base)
|
5
|
+
super
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
# This module contains methods to create validations of uploaded files. All methods
|
10
|
+
# in this module will be included as class methods into <tt>ActiveRecord::Base</tt>
|
11
|
+
# so that you can use them in your models like this:
|
12
|
+
#
|
13
|
+
# class Entry < ActiveRecord::Base
|
14
|
+
# file_column :image
|
15
|
+
# validates_filesize_of :image, :in => 0..1.megabyte
|
16
|
+
# end
|
17
|
+
module ClassMethods
|
18
|
+
EXT_REGEXP = /\.([A-z0-9]+)$/
|
19
|
+
|
20
|
+
# This validates the file type of one or more file_columns. A list of file columns
|
21
|
+
# should be given followed by an options hash.
|
22
|
+
#
|
23
|
+
# Required options:
|
24
|
+
# * <tt>:in</tt> => list of extensions or mime types. If mime types are used they
|
25
|
+
# will be mapped into an extension via FileColumn::ClassMethods::MIME_EXTENSIONS.
|
26
|
+
#
|
27
|
+
# Examples:
|
28
|
+
# validates_file_format_of :field, :in => ["gif", "png", "jpg"]
|
29
|
+
# validates_file_format_of :field, :in => ["image/jpeg"]
|
30
|
+
def validates_file_format_of(*attrs)
|
31
|
+
|
32
|
+
options = attrs.pop if attrs.last.is_a?Hash
|
33
|
+
raise ArgumentError, "Please include the :in option." if !options || !options[:in]
|
34
|
+
options[:in] = [options[:in]] if options[:in].is_a?String
|
35
|
+
raise ArgumentError, "Invalid value for option :in" unless options[:in].is_a?Array
|
36
|
+
|
37
|
+
validates_each(attrs, options) do |record, attr, value|
|
38
|
+
unless value.blank?
|
39
|
+
mime_extensions = record.send("#{attr}_options")[:mime_extensions]
|
40
|
+
extensions = options[:in].map{|o| mime_extensions[o] || o }
|
41
|
+
record.errors.add attr, "is not a valid format." unless extensions.include?(value.scan(EXT_REGEXP).flatten.first)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
# This validates the file size of one or more file_columns. A list of file columns
|
48
|
+
# should be given followed by an options hash.
|
49
|
+
#
|
50
|
+
# Required options:
|
51
|
+
# * <tt>:in</tt> => A size range. Note that you can use ActiveSupport's
|
52
|
+
# numeric extensions for kilobytes, etc.
|
53
|
+
#
|
54
|
+
# Examples:
|
55
|
+
# validates_filesize_of :field, :in => 0..100.megabytes
|
56
|
+
# validates_filesize_of :field, :in => 15.kilobytes..1.megabyte
|
57
|
+
def validates_filesize_of(*attrs)
|
58
|
+
|
59
|
+
options = attrs.pop if attrs.last.is_a?Hash
|
60
|
+
raise ArgumentError, "Please include the :in option." if !options || !options[:in]
|
61
|
+
raise ArgumentError, "Invalid value for option :in" unless options[:in].is_a?Range
|
62
|
+
|
63
|
+
validates_each(attrs, options) do |record, attr, value|
|
64
|
+
unless value.blank?
|
65
|
+
size = File.size(value)
|
66
|
+
record.errors.add attr, "is smaller than the allowed size range." if size < options[:in].first
|
67
|
+
record.errors.add attr, "is larger than the allowed size range." if size > options[:in].last
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
IMAGE_SIZE_REGEXP = /^(\d+)x(\d+)$/
|
74
|
+
|
75
|
+
# Validates the image size of one or more file_columns. A list of file columns
|
76
|
+
# should be given followed by an options hash. The validation will pass
|
77
|
+
# if both image dimensions (rows and columns) are at least as big as
|
78
|
+
# given in the <tt>:min</tt> option.
|
79
|
+
#
|
80
|
+
# Required options:
|
81
|
+
# * <tt>:min</tt> => minimum image dimension string, in the format NNxNN
|
82
|
+
# (columns x rows).
|
83
|
+
#
|
84
|
+
# Example:
|
85
|
+
# validates_image_size :field, :min => "1200x1800"
|
86
|
+
#
|
87
|
+
# This validation requires RMagick to be installed on your system
|
88
|
+
# to check the image's size.
|
89
|
+
def validates_image_size(*attrs)
|
90
|
+
options = attrs.pop if attrs.last.is_a?Hash
|
91
|
+
raise ArgumentError, "Please include a :min option." if !options || !options[:min]
|
92
|
+
minimums = options[:min].scan(IMAGE_SIZE_REGEXP).first.collect{|n| n.to_i} rescue []
|
93
|
+
raise ArgumentError, "Invalid value for option :min (should be 'XXxYY')" unless minimums.size == 2
|
94
|
+
|
95
|
+
require 'RMagick'
|
96
|
+
|
97
|
+
validates_each(attrs, options) do |record, attr, value|
|
98
|
+
unless value.blank?
|
99
|
+
begin
|
100
|
+
img = ::Magick::Image::read(value).first
|
101
|
+
record.errors.add('image', "is too small, must be at least #{minimums[0]}x#{minimums[1]}") if ( img.rows < minimums[1] || img.columns < minimums[0] )
|
102
|
+
rescue ::Magick::ImageMagickError
|
103
|
+
record.errors.add('image', "invalid image")
|
104
|
+
end
|
105
|
+
img = nil
|
106
|
+
GC.start
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/s3_env.example
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_support'
|
5
|
+
require 'active_record'
|
6
|
+
require 'action_view'
|
7
|
+
require 'action_controller'
|
8
|
+
require File.dirname(__FILE__) + '/connection'
|
9
|
+
require 'stringio'
|
10
|
+
|
11
|
+
RAILS_ROOT = File.dirname(__FILE__)
|
12
|
+
RAILS_ENV = ""
|
13
|
+
|
14
|
+
$: << "../lib"
|
15
|
+
|
16
|
+
require 'file_column'
|
17
|
+
require 'file_column_helper'
|
18
|
+
require 'file_compat'
|
19
|
+
require 'validations'
|
20
|
+
require 'test_case'
|
21
|
+
|
22
|
+
# do not use the file executable normally in our tests as
|
23
|
+
# it may not be present on the machine we are running on
|
24
|
+
FileColumn::ClassMethods::DEFAULT_OPTIONS =
|
25
|
+
FileColumn::ClassMethods::DEFAULT_OPTIONS.merge({:file_exec => nil})
|
26
|
+
|
27
|
+
class ActiveRecord::Base
|
28
|
+
include FileColumn
|
29
|
+
include FileColumn::Validations
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
class RequestMock
|
34
|
+
attr_accessor :relative_url_root
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
@relative_url_root = ""
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Test::Unit::TestCase
|
42
|
+
|
43
|
+
def assert_equal_paths(expected_path, path)
|
44
|
+
assert_equal normalize_path(expected_path), normalize_path(path)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def normalize_path(path)
|
51
|
+
Pathname.new(path).realpath
|
52
|
+
end
|
53
|
+
|
54
|
+
def clear_validations
|
55
|
+
[:validate, :validate_on_create, :validate_on_update].each do |attr|
|
56
|
+
Entry.write_inheritable_attribute attr, []
|
57
|
+
Movie.write_inheritable_attribute attr, []
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def file_path(filename)
|
62
|
+
File.expand_path("#{File.dirname(__FILE__)}/fixtures/#{filename}")
|
63
|
+
end
|
64
|
+
|
65
|
+
alias_method :f, :file_path
|
66
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/abstract_unit'
|
2
|
+
require 'active_support/test_case'
|
3
|
+
|
4
|
+
class AttachementStoreTest < Test::Unit::TestCase
|
5
|
+
extend Test::Unit::Assertions
|
6
|
+
|
7
|
+
STORE_DIR = File.dirname(__FILE__)+"/public/entry"
|
8
|
+
STORE_BUILD_OPTS = [[:filesystem]]
|
9
|
+
if !ENV["S3_ACCESS_KEY_ID"].blank?
|
10
|
+
STORE_BUILD_OPTS << [:s3, {
|
11
|
+
:access_key_id => ENV["S3_ACCESS_KEY_ID"],
|
12
|
+
:secret_access_key => ENV["S3_SECRET_ACCESS_KEY"],
|
13
|
+
:bucket_name => ENV["S3_BUCKET_NAME"]}]
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
FileColumn.store(STORE_DIR).clear
|
18
|
+
FileUtils.rm_rf("/tmp/file_column_test")
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.store_test(test_name, store_type, *store_building_args, &block)
|
22
|
+
define_method(test_name + "_for_#{store_type}_store") do
|
23
|
+
FileColumn.store = store_type, *store_building_args
|
24
|
+
yield
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
STORE_BUILD_OPTS.each do |store_type, *rest_args|
|
30
|
+
store_test "test_build_right_store", store_type, *rest_args do
|
31
|
+
assert FileColumn.store("/tmp/attachements").class.name.include?(ActiveSupport::Inflector.camelize(store_type))
|
32
|
+
end
|
33
|
+
|
34
|
+
store_test "test_upload_local_file", store_type, *rest_args do
|
35
|
+
file = "/tmp/file_column_test/abc"
|
36
|
+
FileUtils.mkdir_p(File.dirname(file))
|
37
|
+
FileUtils.touch(file)
|
38
|
+
store = FileColumn.store(STORE_DIR)
|
39
|
+
store.upload("x/y/z", file)
|
40
|
+
assert !store.exists?("x/abc")
|
41
|
+
assert store.exists?("x/y/z/abc")
|
42
|
+
assert_equal "", store.read("x/y/z/abc")
|
43
|
+
end
|
44
|
+
|
45
|
+
store_test "test_upload_with_same_name_replace_file", store_type, *rest_args do
|
46
|
+
file = "/tmp/file_column_test/abc"
|
47
|
+
FileUtils.mkdir_p(File.dirname(file))
|
48
|
+
File.open(file, "w+") { |f| f << "123" }
|
49
|
+
|
50
|
+
store = FileColumn.store(STORE_DIR)
|
51
|
+
store.upload("x/y/z", file)
|
52
|
+
|
53
|
+
assert_equal "123", store.read("x/y/z/abc")
|
54
|
+
|
55
|
+
File.open(file, "w+") { |f| f << "456" }
|
56
|
+
store.upload("x/y/z", file)
|
57
|
+
|
58
|
+
assert_equal "456", store.read("x/y/z/abc")
|
59
|
+
end
|
60
|
+
|
61
|
+
store_test "test_upload_local_dir", store_type, *rest_args do
|
62
|
+
local_dir = "/tmp/file_column_test"
|
63
|
+
FileUtils.mkdir_p(local_dir)
|
64
|
+
FileUtils.touch(File.join(local_dir, "a"))
|
65
|
+
FileUtils.touch(File.join(local_dir, "b"))
|
66
|
+
|
67
|
+
store = FileColumn.store(STORE_DIR)
|
68
|
+
store.upload_dir("x/y/z", local_dir)
|
69
|
+
|
70
|
+
assert store.exists?("x/y/z/a")
|
71
|
+
assert store.exists?("x/y/z/b")
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
store_test "test_upload_local_dir_with_replace_files", store_type, *rest_args do
|
76
|
+
|
77
|
+
local_dir = "/tmp/file_column_test/old"
|
78
|
+
FileUtils.mkdir_p(local_dir)
|
79
|
+
FileUtils.touch(File.join(local_dir, "a"))
|
80
|
+
|
81
|
+
store = FileColumn.store(STORE_DIR)
|
82
|
+
store.upload_dir("x/y/z", local_dir)
|
83
|
+
|
84
|
+
local_dir = "/tmp/file_column_test/new"
|
85
|
+
FileUtils.mkdir_p(local_dir)
|
86
|
+
FileUtils.touch(File.join(local_dir, "b"))
|
87
|
+
|
88
|
+
store = FileColumn.store(STORE_DIR)
|
89
|
+
store.upload_dir("x/y/z", local_dir)
|
90
|
+
|
91
|
+
assert store.exists?("x/y/z/b")
|
92
|
+
assert !store.exists?("x/y/z/a")
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
data/test/connection.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/abstract_unit'
|
2
|
+
require File.dirname(__FILE__) + '/fixtures/entry'
|
3
|
+
|
4
|
+
class UrlForFileColumnTest < Test::Unit::TestCase
|
5
|
+
include FileColumnHelper
|
6
|
+
|
7
|
+
def setup
|
8
|
+
Entry.file_column :image
|
9
|
+
@request = RequestMock.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_url_for_file_column_with_temp_entry
|
13
|
+
@e = Entry.new(:image => upload(f("skanthak.png")))
|
14
|
+
url = url_for_file_column("e", "image")
|
15
|
+
assert_match %r{^/entry/image/tmp/\d+(\.\d+)+/skanthak.png$}, url
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_url_for_file_column_with_saved_entry
|
19
|
+
@e = Entry.new(:image => upload(f("skanthak.png")))
|
20
|
+
assert @e.save
|
21
|
+
|
22
|
+
url = url_for_file_column("e", "image")
|
23
|
+
assert_equal "/entry/image/#{@e.file_column_relative_path_prefix}/skanthak.png", url
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_url_for_file_column_works_with_symbol
|
27
|
+
@e = Entry.new(:image => upload(f("skanthak.png")))
|
28
|
+
assert @e.save
|
29
|
+
|
30
|
+
url = url_for_file_column(:e, :image)
|
31
|
+
assert_equal "/entry/image/#{@e.file_column_relative_path_prefix}/skanthak.png", url
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_url_for_file_column_works_with_object
|
35
|
+
e = Entry.new(:image => upload(f("skanthak.png")))
|
36
|
+
assert e.save
|
37
|
+
|
38
|
+
url = url_for_file_column(e, "image")
|
39
|
+
assert_equal "/entry/image/#{e.file_column_relative_path_prefix}/skanthak.png", url
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_url_for_file_column_should_return_nil_on_no_uploaded_file
|
43
|
+
e = Entry.new
|
44
|
+
assert_nil url_for_file_column(e, "image")
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_url_for_file_column_without_extension
|
48
|
+
e = Entry.new
|
49
|
+
e.image = uploaded_file(file_path("kerb.jpg"), "something/unknown", "local_filename")
|
50
|
+
assert e.save
|
51
|
+
assert_equal "/entry/image/#{e.file_column_relative_path_prefix}/local_filename", url_for_file_column(e, "image")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class UrlForFileColumnTest < Test::Unit::TestCase
|
56
|
+
include FileColumnHelper
|
57
|
+
include ActionView::Helpers::AssetTagHelper
|
58
|
+
include ActionView::Helpers::TagHelper
|
59
|
+
include ActionView::Helpers::UrlHelper
|
60
|
+
|
61
|
+
def setup
|
62
|
+
Entry.file_column :image
|
63
|
+
|
64
|
+
# mock up some request data structures for AssetTagHelper
|
65
|
+
@request = RequestMock.new
|
66
|
+
ActionController::Base.relative_url_root = "/foo/bar"
|
67
|
+
@controller = self
|
68
|
+
end
|
69
|
+
|
70
|
+
def request
|
71
|
+
@request
|
72
|
+
end
|
73
|
+
|
74
|
+
IMAGE_URL = %r{^/foo/bar/entry/image/.+/skanthak.png$}
|
75
|
+
def test_with_image_tag
|
76
|
+
e = Entry.new(:image => upload(f("skanthak.png")))
|
77
|
+
html = image_tag url_for_file_column(e, "image")
|
78
|
+
url = html.scan(/src=\"(.+)\?.*\"/).first.first
|
79
|
+
|
80
|
+
assert_match IMAGE_URL, url
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_with_link_to_tag
|
84
|
+
e = Entry.new(:image => upload(f("skanthak.png")))
|
85
|
+
html = link_to "Download", url_for_file_column(e, "image", :absolute => true)
|
86
|
+
|
87
|
+
url = html.scan(/href=\"(.+)\"/).first.first
|
88
|
+
|
89
|
+
assert_match IMAGE_URL, url
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_relative_url_root_not_modified
|
93
|
+
e = Entry.new(:image => upload(f("skanthak.png")))
|
94
|
+
url_for_file_column(e, "image", :absolute => true)
|
95
|
+
|
96
|
+
assert_equal "/foo/bar", ActionController::Base.relative_url_root
|
97
|
+
end
|
98
|
+
end
|