##// END OF EJS Templates
Merged r13125 (#16700)....
Jean-Philippe Lang -
r12889:a6d62710cd34
parent child
Show More
@@ -1,115 +1,115
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 module Redmine
18 module Redmine
19 module Acts
19 module Acts
20 module Attachable
20 module Attachable
21 def self.included(base)
21 def self.included(base)
22 base.extend ClassMethods
22 base.extend ClassMethods
23 end
23 end
24
24
25 module ClassMethods
25 module ClassMethods
26 def acts_as_attachable(options = {})
26 def acts_as_attachable(options = {})
27 cattr_accessor :attachable_options
27 cattr_accessor :attachable_options
28 self.attachable_options = {}
28 self.attachable_options = {}
29 attachable_options[:view_permission] = options.delete(:view_permission) || "view_#{self.name.pluralize.underscore}".to_sym
29 attachable_options[:view_permission] = options.delete(:view_permission) || "view_#{self.name.pluralize.underscore}".to_sym
30 attachable_options[:delete_permission] = options.delete(:delete_permission) || "edit_#{self.name.pluralize.underscore}".to_sym
30 attachable_options[:delete_permission] = options.delete(:delete_permission) || "edit_#{self.name.pluralize.underscore}".to_sym
31
31
32 has_many :attachments, options.merge(:as => :container,
32 has_many :attachments, options.merge(:as => :container,
33 :order => "#{Attachment.table_name}.created_on ASC, #{Attachment.table_name}.id ASC",
33 :order => "#{Attachment.table_name}.created_on ASC, #{Attachment.table_name}.id ASC",
34 :dependent => :destroy)
34 :dependent => :destroy)
35 send :include, Redmine::Acts::Attachable::InstanceMethods
35 send :include, Redmine::Acts::Attachable::InstanceMethods
36 before_save :attach_saved_attachments
36 before_save :attach_saved_attachments
37 end
37 end
38 end
38 end
39
39
40 module InstanceMethods
40 module InstanceMethods
41 def self.included(base)
41 def self.included(base)
42 base.extend ClassMethods
42 base.extend ClassMethods
43 end
43 end
44
44
45 def attachments_visible?(user=User.current)
45 def attachments_visible?(user=User.current)
46 (respond_to?(:visible?) ? visible?(user) : true) &&
46 (respond_to?(:visible?) ? visible?(user) : true) &&
47 user.allowed_to?(self.class.attachable_options[:view_permission], self.project)
47 user.allowed_to?(self.class.attachable_options[:view_permission], self.project)
48 end
48 end
49
49
50 def attachments_deletable?(user=User.current)
50 def attachments_deletable?(user=User.current)
51 (respond_to?(:visible?) ? visible?(user) : true) &&
51 (respond_to?(:visible?) ? visible?(user) : true) &&
52 user.allowed_to?(self.class.attachable_options[:delete_permission], self.project)
52 user.allowed_to?(self.class.attachable_options[:delete_permission], self.project)
53 end
53 end
54
54
55 def saved_attachments
55 def saved_attachments
56 @saved_attachments ||= []
56 @saved_attachments ||= []
57 end
57 end
58
58
59 def unsaved_attachments
59 def unsaved_attachments
60 @unsaved_attachments ||= []
60 @unsaved_attachments ||= []
61 end
61 end
62
62
63 def save_attachments(attachments, author=User.current)
63 def save_attachments(attachments, author=User.current)
64 if attachments.is_a?(Hash)
64 if attachments.is_a?(Hash)
65 attachments = attachments.stringify_keys
65 attachments = attachments.stringify_keys
66 attachments = attachments.to_a.sort {|a, b|
66 attachments = attachments.to_a.sort {|a, b|
67 if a.first.to_i > 0 && b.first.to_i > 0
67 if a.first.to_i > 0 && b.first.to_i > 0
68 a.first.to_i <=> b.first.to_i
68 a.first.to_i <=> b.first.to_i
69 elsif a.first.to_i > 0
69 elsif a.first.to_i > 0
70 1
70 1
71 elsif b.first.to_i > 0
71 elsif b.first.to_i > 0
72 -1
72 -1
73 else
73 else
74 a.first <=> b.first
74 a.first <=> b.first
75 end
75 end
76 }
76 }
77 attachments = attachments.map(&:last)
77 attachments = attachments.map(&:last)
78 end
78 end
79 if attachments.is_a?(Array)
79 if attachments.is_a?(Array)
80 attachments.each do |attachment|
80 attachments.each do |attachment|
81 next unless attachment.is_a?(Hash)
81 next unless attachment.is_a?(Hash)
82 a = nil
82 a = nil
83 if file = attachment['file']
83 if file = attachment['file']
84 next unless file.size > 0
84 next unless file.size > 0
85 a = Attachment.create(:file => file, :author => author)
85 a = Attachment.create(:file => file, :author => author)
86 elsif token = attachment['token']
86 elsif token = attachment['token']
87 a = Attachment.find_by_token(token)
87 a = Attachment.find_by_token(token)
88 next unless a
88 next unless a
89 a.filename = attachment['filename'] unless attachment['filename'].blank?
89 a.filename = attachment['filename'] unless attachment['filename'].blank?
90 a.content_type = attachment['content_type']
90 a.content_type = attachment['content_type'] unless attachment['content_type'].blank?
91 end
91 end
92 next unless a
92 next unless a
93 a.description = attachment['description'].to_s.strip
93 a.description = attachment['description'].to_s.strip
94 if a.new_record?
94 if a.new_record?
95 unsaved_attachments << a
95 unsaved_attachments << a
96 else
96 else
97 saved_attachments << a
97 saved_attachments << a
98 end
98 end
99 end
99 end
100 end
100 end
101 {:files => saved_attachments, :unsaved => unsaved_attachments}
101 {:files => saved_attachments, :unsaved => unsaved_attachments}
102 end
102 end
103
103
104 def attach_saved_attachments
104 def attach_saved_attachments
105 saved_attachments.each do |attachment|
105 saved_attachments.each do |attachment|
106 self.attachments << attachment
106 self.attachments << attachment
107 end
107 end
108 end
108 end
109
109
110 module ClassMethods
110 module ClassMethods
111 end
111 end
112 end
112 end
113 end
113 end
114 end
114 end
115 end
115 end
@@ -1,289 +1,298
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2014 Jean-Philippe Lang
4 # Copyright (C) 2006-2014 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 require File.expand_path('../../test_helper', __FILE__)
20 require File.expand_path('../../test_helper', __FILE__)
21
21
22 class AttachmentTest < ActiveSupport::TestCase
22 class AttachmentTest < ActiveSupport::TestCase
23 fixtures :users, :projects, :roles, :members, :member_roles,
23 fixtures :users, :projects, :roles, :members, :member_roles,
24 :enabled_modules, :issues, :trackers, :attachments
24 :enabled_modules, :issues, :trackers, :attachments
25
25
26 class MockFile
26 class MockFile
27 attr_reader :original_filename, :content_type, :content, :size
27 attr_reader :original_filename, :content_type, :content, :size
28
28
29 def initialize(attributes)
29 def initialize(attributes)
30 @original_filename = attributes[:original_filename]
30 @original_filename = attributes[:original_filename]
31 @content_type = attributes[:content_type]
31 @content_type = attributes[:content_type]
32 @content = attributes[:content] || "Content"
32 @content = attributes[:content] || "Content"
33 @size = content.size
33 @size = content.size
34 end
34 end
35 end
35 end
36
36
37 def setup
37 def setup
38 set_tmp_attachments_directory
38 set_tmp_attachments_directory
39 end
39 end
40
40
41 def test_container_for_new_attachment_should_be_nil
41 def test_container_for_new_attachment_should_be_nil
42 assert_nil Attachment.new.container
42 assert_nil Attachment.new.container
43 end
43 end
44
44
45 def test_filename_should_remove_eols
45 def test_filename_should_remove_eols
46 assert_equal "line_feed", Attachment.new(:filename => "line\nfeed").filename
46 assert_equal "line_feed", Attachment.new(:filename => "line\nfeed").filename
47 assert_equal "line_feed", Attachment.new(:filename => "some\npath/line\nfeed").filename
47 assert_equal "line_feed", Attachment.new(:filename => "some\npath/line\nfeed").filename
48 assert_equal "carriage_return", Attachment.new(:filename => "carriage\rreturn").filename
48 assert_equal "carriage_return", Attachment.new(:filename => "carriage\rreturn").filename
49 assert_equal "carriage_return", Attachment.new(:filename => "some\rpath/carriage\rreturn").filename
49 assert_equal "carriage_return", Attachment.new(:filename => "some\rpath/carriage\rreturn").filename
50 end
50 end
51
51
52 def test_create
52 def test_create
53 a = Attachment.new(:container => Issue.find(1),
53 a = Attachment.new(:container => Issue.find(1),
54 :file => uploaded_test_file("testfile.txt", "text/plain"),
54 :file => uploaded_test_file("testfile.txt", "text/plain"),
55 :author => User.find(1))
55 :author => User.find(1))
56 assert a.save
56 assert a.save
57 assert_equal 'testfile.txt', a.filename
57 assert_equal 'testfile.txt', a.filename
58 assert_equal 59, a.filesize
58 assert_equal 59, a.filesize
59 assert_equal 'text/plain', a.content_type
59 assert_equal 'text/plain', a.content_type
60 assert_equal 0, a.downloads
60 assert_equal 0, a.downloads
61 assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
61 assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
62
62
63 assert a.disk_directory
63 assert a.disk_directory
64 assert_match %r{\A\d{4}/\d{2}\z}, a.disk_directory
64 assert_match %r{\A\d{4}/\d{2}\z}, a.disk_directory
65
65
66 assert File.exist?(a.diskfile)
66 assert File.exist?(a.diskfile)
67 assert_equal 59, File.size(a.diskfile)
67 assert_equal 59, File.size(a.diskfile)
68 end
68 end
69
69
70 def test_copy_should_preserve_attributes
70 def test_copy_should_preserve_attributes
71 a = Attachment.find(1)
71 a = Attachment.find(1)
72 copy = a.copy
72 copy = a.copy
73
73
74 assert_save copy
74 assert_save copy
75 copy = Attachment.order('id DESC').first
75 copy = Attachment.order('id DESC').first
76 %w(filename filesize content_type author_id created_on description digest disk_filename disk_directory diskfile).each do |attribute|
76 %w(filename filesize content_type author_id created_on description digest disk_filename disk_directory diskfile).each do |attribute|
77 assert_equal a.send(attribute), copy.send(attribute), "#{attribute} was different"
77 assert_equal a.send(attribute), copy.send(attribute), "#{attribute} was different"
78 end
78 end
79 end
79 end
80
80
81 def test_size_should_be_validated_for_new_file
81 def test_size_should_be_validated_for_new_file
82 with_settings :attachment_max_size => 0 do
82 with_settings :attachment_max_size => 0 do
83 a = Attachment.new(:container => Issue.find(1),
83 a = Attachment.new(:container => Issue.find(1),
84 :file => uploaded_test_file("testfile.txt", "text/plain"),
84 :file => uploaded_test_file("testfile.txt", "text/plain"),
85 :author => User.find(1))
85 :author => User.find(1))
86 assert !a.save
86 assert !a.save
87 end
87 end
88 end
88 end
89
89
90 def test_size_should_not_be_validated_when_copying
90 def test_size_should_not_be_validated_when_copying
91 a = Attachment.create!(:container => Issue.find(1),
91 a = Attachment.create!(:container => Issue.find(1),
92 :file => uploaded_test_file("testfile.txt", "text/plain"),
92 :file => uploaded_test_file("testfile.txt", "text/plain"),
93 :author => User.find(1))
93 :author => User.find(1))
94 with_settings :attachment_max_size => 0 do
94 with_settings :attachment_max_size => 0 do
95 copy = a.copy
95 copy = a.copy
96 assert copy.save
96 assert copy.save
97 end
97 end
98 end
98 end
99
99
100 def test_description_length_should_be_validated
100 def test_description_length_should_be_validated
101 a = Attachment.new(:description => 'a' * 300)
101 a = Attachment.new(:description => 'a' * 300)
102 assert !a.save
102 assert !a.save
103 assert_not_equal [], a.errors[:description]
103 assert_not_equal [], a.errors[:description]
104 end
104 end
105
105
106 def test_destroy
106 def test_destroy
107 a = Attachment.new(:container => Issue.find(1),
107 a = Attachment.new(:container => Issue.find(1),
108 :file => uploaded_test_file("testfile.txt", "text/plain"),
108 :file => uploaded_test_file("testfile.txt", "text/plain"),
109 :author => User.find(1))
109 :author => User.find(1))
110 assert a.save
110 assert a.save
111 assert_equal 'testfile.txt', a.filename
111 assert_equal 'testfile.txt', a.filename
112 assert_equal 59, a.filesize
112 assert_equal 59, a.filesize
113 assert_equal 'text/plain', a.content_type
113 assert_equal 'text/plain', a.content_type
114 assert_equal 0, a.downloads
114 assert_equal 0, a.downloads
115 assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
115 assert_equal '1478adae0d4eb06d35897518540e25d6', a.digest
116 diskfile = a.diskfile
116 diskfile = a.diskfile
117 assert File.exist?(diskfile)
117 assert File.exist?(diskfile)
118 assert_equal 59, File.size(a.diskfile)
118 assert_equal 59, File.size(a.diskfile)
119 assert a.destroy
119 assert a.destroy
120 assert !File.exist?(diskfile)
120 assert !File.exist?(diskfile)
121 end
121 end
122
122
123 def test_destroy_should_not_delete_file_referenced_by_other_attachment
123 def test_destroy_should_not_delete_file_referenced_by_other_attachment
124 a = Attachment.create!(:container => Issue.find(1),
124 a = Attachment.create!(:container => Issue.find(1),
125 :file => uploaded_test_file("testfile.txt", "text/plain"),
125 :file => uploaded_test_file("testfile.txt", "text/plain"),
126 :author => User.find(1))
126 :author => User.find(1))
127 diskfile = a.diskfile
127 diskfile = a.diskfile
128
128
129 copy = a.copy
129 copy = a.copy
130 copy.save!
130 copy.save!
131
131
132 assert File.exists?(diskfile)
132 assert File.exists?(diskfile)
133 a.destroy
133 a.destroy
134 assert File.exists?(diskfile)
134 assert File.exists?(diskfile)
135 copy.destroy
135 copy.destroy
136 assert !File.exists?(diskfile)
136 assert !File.exists?(diskfile)
137 end
137 end
138
138
139 def test_create_should_auto_assign_content_type
139 def test_create_should_auto_assign_content_type
140 a = Attachment.new(:container => Issue.find(1),
140 a = Attachment.new(:container => Issue.find(1),
141 :file => uploaded_test_file("testfile.txt", ""),
141 :file => uploaded_test_file("testfile.txt", ""),
142 :author => User.find(1))
142 :author => User.find(1))
143 assert a.save
143 assert a.save
144 assert_equal 'text/plain', a.content_type
144 assert_equal 'text/plain', a.content_type
145 end
145 end
146
146
147 def test_identical_attachments_at_the_same_time_should_not_overwrite
147 def test_identical_attachments_at_the_same_time_should_not_overwrite
148 a1 = Attachment.create!(:container => Issue.find(1),
148 a1 = Attachment.create!(:container => Issue.find(1),
149 :file => uploaded_test_file("testfile.txt", ""),
149 :file => uploaded_test_file("testfile.txt", ""),
150 :author => User.find(1))
150 :author => User.find(1))
151 a2 = Attachment.create!(:container => Issue.find(1),
151 a2 = Attachment.create!(:container => Issue.find(1),
152 :file => uploaded_test_file("testfile.txt", ""),
152 :file => uploaded_test_file("testfile.txt", ""),
153 :author => User.find(1))
153 :author => User.find(1))
154 assert a1.disk_filename != a2.disk_filename
154 assert a1.disk_filename != a2.disk_filename
155 end
155 end
156
156
157 def test_filename_should_be_basenamed
157 def test_filename_should_be_basenamed
158 a = Attachment.new(:file => MockFile.new(:original_filename => "path/to/the/file"))
158 a = Attachment.new(:file => MockFile.new(:original_filename => "path/to/the/file"))
159 assert_equal 'file', a.filename
159 assert_equal 'file', a.filename
160 end
160 end
161
161
162 def test_filename_should_be_sanitized
162 def test_filename_should_be_sanitized
163 a = Attachment.new(:file => MockFile.new(:original_filename => "valid:[] invalid:?%*|\"'<>chars"))
163 a = Attachment.new(:file => MockFile.new(:original_filename => "valid:[] invalid:?%*|\"'<>chars"))
164 assert_equal 'valid_[] invalid_chars', a.filename
164 assert_equal 'valid_[] invalid_chars', a.filename
165 end
165 end
166
166
167 def test_diskfilename
167 def test_diskfilename
168 assert Attachment.disk_filename("test_file.txt") =~ /^\d{12}_test_file.txt$/
168 assert Attachment.disk_filename("test_file.txt") =~ /^\d{12}_test_file.txt$/
169 assert_equal 'test_file.txt', Attachment.disk_filename("test_file.txt")[13..-1]
169 assert_equal 'test_file.txt', Attachment.disk_filename("test_file.txt")[13..-1]
170 assert_equal '770c509475505f37c2b8fb6030434d6b.txt', Attachment.disk_filename("test_accentuΓ©.txt")[13..-1]
170 assert_equal '770c509475505f37c2b8fb6030434d6b.txt', Attachment.disk_filename("test_accentuΓ©.txt")[13..-1]
171 assert_equal 'f8139524ebb8f32e51976982cd20a85d', Attachment.disk_filename("test_accentuΓ©")[13..-1]
171 assert_equal 'f8139524ebb8f32e51976982cd20a85d', Attachment.disk_filename("test_accentuΓ©")[13..-1]
172 assert_equal 'cbb5b0f30978ba03731d61f9f6d10011', Attachment.disk_filename("test_accentuΓ©.Γ§a")[13..-1]
172 assert_equal 'cbb5b0f30978ba03731d61f9f6d10011', Attachment.disk_filename("test_accentuΓ©.Γ§a")[13..-1]
173 end
173 end
174
174
175 def test_title
175 def test_title
176 a = Attachment.new(:filename => "test.png")
176 a = Attachment.new(:filename => "test.png")
177 assert_equal "test.png", a.title
177 assert_equal "test.png", a.title
178
178
179 a = Attachment.new(:filename => "test.png", :description => "Cool image")
179 a = Attachment.new(:filename => "test.png", :description => "Cool image")
180 assert_equal "test.png (Cool image)", a.title
180 assert_equal "test.png (Cool image)", a.title
181 end
181 end
182
182
183 def test_prune_should_destroy_old_unattached_attachments
183 def test_prune_should_destroy_old_unattached_attachments
184 Attachment.create!(:file => uploaded_test_file("testfile.txt", ""), :author_id => 1, :created_on => 2.days.ago)
184 Attachment.create!(:file => uploaded_test_file("testfile.txt", ""), :author_id => 1, :created_on => 2.days.ago)
185 Attachment.create!(:file => uploaded_test_file("testfile.txt", ""), :author_id => 1, :created_on => 2.days.ago)
185 Attachment.create!(:file => uploaded_test_file("testfile.txt", ""), :author_id => 1, :created_on => 2.days.ago)
186 Attachment.create!(:file => uploaded_test_file("testfile.txt", ""), :author_id => 1)
186 Attachment.create!(:file => uploaded_test_file("testfile.txt", ""), :author_id => 1)
187
187
188 assert_difference 'Attachment.count', -2 do
188 assert_difference 'Attachment.count', -2 do
189 Attachment.prune
189 Attachment.prune
190 end
190 end
191 end
191 end
192
192
193 def test_move_from_root_to_target_directory_should_move_root_files
193 def test_move_from_root_to_target_directory_should_move_root_files
194 a = Attachment.find(20)
194 a = Attachment.find(20)
195 assert a.disk_directory.blank?
195 assert a.disk_directory.blank?
196 # Create a real file for this fixture
196 # Create a real file for this fixture
197 File.open(a.diskfile, "w") do |f|
197 File.open(a.diskfile, "w") do |f|
198 f.write "test file at the root of files directory"
198 f.write "test file at the root of files directory"
199 end
199 end
200 assert a.readable?
200 assert a.readable?
201 Attachment.move_from_root_to_target_directory
201 Attachment.move_from_root_to_target_directory
202
202
203 a.reload
203 a.reload
204 assert_equal '2012/05', a.disk_directory
204 assert_equal '2012/05', a.disk_directory
205 assert a.readable?
205 assert a.readable?
206 end
206 end
207
207
208 test "Attachmnet.attach_files should attach the file" do
208 test "Attachmnet.attach_files should attach the file" do
209 issue = Issue.first
209 issue = Issue.first
210 assert_difference 'Attachment.count' do
210 assert_difference 'Attachment.count' do
211 Attachment.attach_files(issue,
211 Attachment.attach_files(issue,
212 '1' => {
212 '1' => {
213 'file' => uploaded_test_file('testfile.txt', 'text/plain'),
213 'file' => uploaded_test_file('testfile.txt', 'text/plain'),
214 'description' => 'test'
214 'description' => 'test'
215 })
215 })
216 end
216 end
217 attachment = Attachment.order('id DESC').first
217 attachment = Attachment.order('id DESC').first
218 assert_equal issue, attachment.container
218 assert_equal issue, attachment.container
219 assert_equal 'testfile.txt', attachment.filename
219 assert_equal 'testfile.txt', attachment.filename
220 assert_equal 59, attachment.filesize
220 assert_equal 59, attachment.filesize
221 assert_equal 'test', attachment.description
221 assert_equal 'test', attachment.description
222 assert_equal 'text/plain', attachment.content_type
222 assert_equal 'text/plain', attachment.content_type
223 assert File.exists?(attachment.diskfile)
223 assert File.exists?(attachment.diskfile)
224 assert_equal 59, File.size(attachment.diskfile)
224 assert_equal 59, File.size(attachment.diskfile)
225 end
225 end
226
226
227 test "Attachmnet.attach_files should add unsaved files to the object as unsaved attachments" do
227 test "Attachmnet.attach_files should add unsaved files to the object as unsaved attachments" do
228 # Max size of 0 to force Attachment creation failures
228 # Max size of 0 to force Attachment creation failures
229 with_settings(:attachment_max_size => 0) do
229 with_settings(:attachment_max_size => 0) do
230 @project = Project.find(1)
230 @project = Project.find(1)
231 response = Attachment.attach_files(@project, {
231 response = Attachment.attach_files(@project, {
232 '1' => {'file' => mock_file, 'description' => 'test'},
232 '1' => {'file' => mock_file, 'description' => 'test'},
233 '2' => {'file' => mock_file, 'description' => 'test'}
233 '2' => {'file' => mock_file, 'description' => 'test'}
234 })
234 })
235
235
236 assert response[:unsaved].present?
236 assert response[:unsaved].present?
237 assert_equal 2, response[:unsaved].length
237 assert_equal 2, response[:unsaved].length
238 assert response[:unsaved].first.new_record?
238 assert response[:unsaved].first.new_record?
239 assert response[:unsaved].second.new_record?
239 assert response[:unsaved].second.new_record?
240 assert_equal response[:unsaved], @project.unsaved_attachments
240 assert_equal response[:unsaved], @project.unsaved_attachments
241 end
241 end
242 end
242 end
243
243
244 test "Attachment.attach_files should preserve the content_type of attachments added by token" do
245 @project = Project.find(1)
246 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", ""), :author_id => 1, :created_on => 2.days.ago)
247 assert_equal 'text/plain', attachment.content_type
248 Attachment.attach_files(@project, { '1' => {'token' => attachment.token } })
249 attachment.reload
250 assert_equal 'text/plain', attachment.content_type
251 end
252
244 def test_latest_attach
253 def test_latest_attach
245 set_fixtures_attachments_directory
254 set_fixtures_attachments_directory
246 a1 = Attachment.find(16)
255 a1 = Attachment.find(16)
247 assert_equal "testfile.png", a1.filename
256 assert_equal "testfile.png", a1.filename
248 assert a1.readable?
257 assert a1.readable?
249 assert (! a1.visible?(User.anonymous))
258 assert (! a1.visible?(User.anonymous))
250 assert a1.visible?(User.find(2))
259 assert a1.visible?(User.find(2))
251 a2 = Attachment.find(17)
260 a2 = Attachment.find(17)
252 assert_equal "testfile.PNG", a2.filename
261 assert_equal "testfile.PNG", a2.filename
253 assert a2.readable?
262 assert a2.readable?
254 assert (! a2.visible?(User.anonymous))
263 assert (! a2.visible?(User.anonymous))
255 assert a2.visible?(User.find(2))
264 assert a2.visible?(User.find(2))
256 assert a1.created_on < a2.created_on
265 assert a1.created_on < a2.created_on
257
266
258 la1 = Attachment.latest_attach([a1, a2], "testfile.png")
267 la1 = Attachment.latest_attach([a1, a2], "testfile.png")
259 assert_equal 17, la1.id
268 assert_equal 17, la1.id
260 la2 = Attachment.latest_attach([a1, a2], "Testfile.PNG")
269 la2 = Attachment.latest_attach([a1, a2], "Testfile.PNG")
261 assert_equal 17, la2.id
270 assert_equal 17, la2.id
262
271
263 set_tmp_attachments_directory
272 set_tmp_attachments_directory
264 end
273 end
265
274
266 def test_thumbnailable_should_be_true_for_images
275 def test_thumbnailable_should_be_true_for_images
267 assert_equal true, Attachment.new(:filename => 'test.jpg').thumbnailable?
276 assert_equal true, Attachment.new(:filename => 'test.jpg').thumbnailable?
268 end
277 end
269
278
270 def test_thumbnailable_should_be_true_for_non_images
279 def test_thumbnailable_should_be_true_for_non_images
271 assert_equal false, Attachment.new(:filename => 'test.txt').thumbnailable?
280 assert_equal false, Attachment.new(:filename => 'test.txt').thumbnailable?
272 end
281 end
273
282
274 if convert_installed?
283 if convert_installed?
275 def test_thumbnail_should_generate_the_thumbnail
284 def test_thumbnail_should_generate_the_thumbnail
276 set_fixtures_attachments_directory
285 set_fixtures_attachments_directory
277 attachment = Attachment.find(16)
286 attachment = Attachment.find(16)
278 Attachment.clear_thumbnails
287 Attachment.clear_thumbnails
279
288
280 assert_difference "Dir.glob(File.join(Attachment.thumbnails_storage_path, '*.thumb')).size" do
289 assert_difference "Dir.glob(File.join(Attachment.thumbnails_storage_path, '*.thumb')).size" do
281 thumbnail = attachment.thumbnail
290 thumbnail = attachment.thumbnail
282 assert_equal "16_8e0294de2441577c529f170b6fb8f638_100.thumb", File.basename(thumbnail)
291 assert_equal "16_8e0294de2441577c529f170b6fb8f638_100.thumb", File.basename(thumbnail)
283 assert File.exists?(thumbnail)
292 assert File.exists?(thumbnail)
284 end
293 end
285 end
294 end
286 else
295 else
287 puts '(ImageMagick convert not available)'
296 puts '(ImageMagick convert not available)'
288 end
297 end
289 end
298 end
General Comments 0
You need to be logged in to leave comments. Login now