Едно от основните неща който се налага да има в едно приложение е качване на файлове. И докато за PHP работата с прикачени файлове се учи и прави твърде лесно. При Rails е малко по-трудно, но пък за това има множество плъгини, които улесняват този процес. Най-много ми допада Paperclip, на Thoughtbot. На Thoughtbot използвам и още две техни неща Factory Girl и Shoulda, както и наблюдавам и развитието на Clearance.
Исках и да тествам дали Paperclip е наместен както трябва в моето приложение. Което е доста лесно. Проблемът е, че липсва каквато и да е документация по въпроса. Но съм малко ровене в ruby кода и опити успях да разбера как става това. И тъй като може и на други хора да им трябва подобно нещо реших да споделя наученото.
За тестване използвам RSpec с малко помощ от Shoulda. А Paperclip го използвам като plugin, а не като gem (което за този пост мисля, че няма голямо значение).
Така, по същество. От Thoughtbot са сложили в самия Paperclip четири валидиращи метода (намират се в lib/paperclip/matchers.rb):
- have_attached_file
- validate_attachment_presence
- validate_attachment_size
- validate_attachment_content_type
Лошото е че в документацията на Paperclip, няма много(да не кажа никаква) информация за тях, като начин на ползване и как да се добавят в тестовете.
Добавяне на matcher-ите в RSpec тестовете
Това се оказа по-лесно от колкото предполагах просто във вашия spec_helper.rb добавяте следното:
require 'paperclip/matchers' Spec::Runner.configure do |config| config.include Paperclip::Shoulda::Matchers end
И воала вече може да използвате горе споменатите matcher-и. Обаче с малко засрамено ще кажа, че ми отне доста време да стигна до тези редове. Много ми помогна този урок от Railscasts – RSpec Matchers & Macros.
Същинското тестване
Тук нещата не са толкова трудни, но много зависи от съответните изисквания за вашето приложение.
class Product < ActiveRecord::Base
has_attached_file :picture,
:path => ":rails_root/public/files/:class/:id/:style.:extension",
:styles => {:original => "800x600>", :small => "102x76" }
end
describe Product do
it { Product.should have_attached_file(:picture) }
it { Product.should validate_attachment_presence(:picture) }
it { Product.should validate_attachment_size(:picture).in(1..1.megabytes) }
it { Product.should validate_attachment_content_type(:picture).
allowing(%w(image/png image/jpeg)).
rejecting(%w(audio/mp3 application/octet-stream)) }
end
Според мен този код говори сам за себе си.
Неща които трябва да се отбележат. Първото, за разлика от повечето Shoulda matcherи не може да се ползва само “should”, а трябва да се пише името на модела, който се тества “Product.should”. Другото нещо което ми отне малко повече време да го разбера. А именно, че validate_attachment_content_type когато се вика трябва задължително да има allowing и rejecting, който описват типовете който може да се ползват за дадения файл.
Лично за мен беше доста полезно да видя как работят Paperclip matcherи от вътре.
Надявам се да съм бил полезен на някого с този пост и да съм му спестил време в ровене и търсене
Ако някой има идеи и предложение ще се радвам да ги чуя.
