attachs 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +254 -0
  4. data/Rakefile +0 -2
  5. data/lib/attachs.rb +37 -10
  6. data/lib/attachs/active_record/base.rb +58 -95
  7. data/lib/attachs/active_record/connection_adapters.rb +40 -0
  8. data/lib/attachs/active_record/migration.rb +17 -0
  9. data/lib/attachs/active_record/validators.rb +7 -0
  10. data/lib/attachs/active_record/validators/attachment_content_type_validator.rb +30 -0
  11. data/lib/attachs/active_record/validators/attachment_presence_validator.rb +22 -0
  12. data/lib/attachs/active_record/validators/attachment_size_validator.rb +39 -0
  13. data/lib/attachs/attachment.rb +114 -0
  14. data/{config → lib/attachs}/locales/en.yml +2 -1
  15. data/{config → lib/attachs}/locales/es.yml +2 -1
  16. data/lib/attachs/railtie.rb +31 -11
  17. data/lib/attachs/storages/base.rb +68 -0
  18. data/lib/attachs/storages/local.rb +61 -37
  19. data/lib/attachs/storages/s3.rb +66 -57
  20. data/lib/attachs/tools/magick.rb +52 -0
  21. data/lib/attachs/types/base.rb +22 -0
  22. data/lib/attachs/types/default.rb +21 -0
  23. data/lib/attachs/types/regular.rb +21 -0
  24. data/lib/attachs/version.rb +1 -1
  25. data/lib/generators/attachs/install_generator.rb +13 -0
  26. data/lib/generators/attachs/templates/attachs.rb +2 -0
  27. data/lib/tasks/attachs.rake +30 -0
  28. data/test/attachment_test.rb +19 -0
  29. data/test/dummy/app/models/medium.rb +5 -0
  30. data/test/dummy/app/models/picture.rb +2 -0
  31. data/test/dummy/config/application.rb +1 -7
  32. data/test/dummy/config/initializers/attachs.rb +25 -0
  33. data/test/dummy/config/initializers/secret_token.rb +1 -0
  34. data/test/dummy/config/routes.rb +0 -1
  35. data/test/dummy/db/migrate/20140808012639_create_media.rb +11 -0
  36. data/test/dummy/db/schema.rb +14 -25
  37. data/test/dummy/log/development.log +9 -27
  38. data/test/dummy/log/test.log +52130 -11207
  39. data/test/dummy/test/fixtures/180x150.gif +0 -0
  40. data/test/generator_test.rb +18 -0
  41. data/test/local_storage_test.rb +57 -0
  42. data/test/magick_tool_test.rb +42 -0
  43. data/test/migration_test.rb +65 -0
  44. data/test/s3_storage_tes.rb +56 -0
  45. data/test/tasks_test.rb +61 -0
  46. data/test/test_helper.rb +17 -17
  47. data/test/validators_test.rb +100 -0
  48. metadata +85 -120
  49. data/README.rdoc +0 -104
  50. data/app/controllers/attachs/presets_controller.rb +0 -17
  51. data/config/routes.rb +0 -5
  52. data/lib/attachs/engine.rb +0 -7
  53. data/lib/attachs/magick/image.rb +0 -85
  54. data/lib/attachs/types/file.rb +0 -131
  55. data/lib/attachs/types/image.rb +0 -58
  56. data/lib/attachs/validators/attachment_content_type_validator.rb +0 -11
  57. data/lib/attachs/validators/attachment_presence_validator.rb +0 -9
  58. data/lib/attachs/validators/attachment_size_validator.rb +0 -21
  59. data/lib/attachs/validators/base.rb +0 -13
  60. data/lib/generators/attachs/s3/config_generator.rb +0 -13
  61. data/lib/generators/attachs/s3/templates/s3.yml +0 -16
  62. data/lib/tasks/attachs_tasks.rake +0 -71
  63. data/test/dummy/app/models/all_attached.rb +0 -16
  64. data/test/dummy/app/models/file_attached.rb +0 -3
  65. data/test/dummy/app/models/image_attached.rb +0 -3
  66. data/test/dummy/app/models/private_file_attached.rb +0 -3
  67. data/test/dummy/app/models/private_image_attached.rb +0 -3
  68. data/test/dummy/db/migrate/20130820222342_create_file_attacheds.rb +0 -9
  69. data/test/dummy/db/migrate/20130820222355_create_image_attacheds.rb +0 -9
  70. data/test/dummy/db/migrate/20130820222534_create_all_attacheds.rb +0 -19
  71. data/test/dummy/public/uploads/files/file.txt +0 -1
  72. data/test/dummy/public/uploads/images/big/image.jpg +0 -0
  73. data/test/dummy/public/uploads/images/original/image.jpg +0 -0
  74. data/test/dummy/public/uploads/images/small/image.jpg +0 -0
  75. data/test/dummy/test/fixtures/file_big.txt +0 -1
  76. data/test/dummy/test/fixtures/file_empty.txt +0 -1
  77. data/test/dummy/test/fixtures/image.jpg +0 -0
  78. data/test/dummy/test/fixtures/image_big.jpg +0 -0
  79. data/test/dummy/test/fixtures/image_empty.jpg +0 -0
  80. data/test/dummy/tmp/uploads/files/13898788260004868.txt +0 -1
  81. data/test/local_file_record_test.rb +0 -31
  82. data/test/local_file_string_test.rb +0 -23
  83. data/test/local_file_upload_test.rb +0 -30
  84. data/test/local_generate_test.rb +0 -25
  85. data/test/local_image_record_test.rb +0 -25
  86. data/test/local_image_string_test.rb +0 -34
  87. data/test/local_image_upload_test.rb +0 -27
  88. data/test/local_records_test.rb +0 -52
  89. data/test/local_validators_test.rb +0 -71
  90. data/test/s3_file_record_tes.rb +0 -21
  91. data/test/s3_file_string_tes.rb +0 -24
  92. data/test/s3_file_upload_tes.rb +0 -31
  93. data/test/s3_image_record_tes.rb +0 -26
  94. data/test/s3_image_string_tes.rb +0 -31
  95. data/test/s3_image_upload_tes.rb +0 -28
  96. data/test/s3_records_tes.rb +0 -56
  97. data/test/s3_validators_tes.rb +0 -72
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+ require 'rails/generators'
3
+ require 'generators/attachs/install_generator'
4
+
5
+ class GeneratorsTest < Rails::Generators::TestCase
6
+ tests Attachs::InstallGenerator
7
+ destination File.expand_path('../tmp', File.dirname(__FILE__))
8
+
9
+ teardown do
10
+ FileUtils.rm_rf self.destination_root
11
+ end
12
+
13
+ test 'initializer generator' do
14
+ run_generator
15
+ assert_file 'config/initializers/attachs.rb'
16
+ end
17
+
18
+ end
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+
3
+ class LocalStorageTest < ActiveSupport::TestCase
4
+
5
+ test 'file url' do
6
+ medium = Medium.create(local_attach: file_upload)
7
+ assert_equal file_url, medium.local_attach.url
8
+ end
9
+
10
+ test 'image url' do
11
+ medium = Medium.create(local_attach: image_upload)
12
+ assert_equal image_url, medium.local_attach.url
13
+ assert_equal image_url(:small), medium.local_attach.url(:small)
14
+ end
15
+
16
+ test 'crud' do
17
+ medium = Medium.create(local_attach: file_upload)
18
+ assert File.exist?(file_path)
19
+ medium.update_attributes! local_attach: image_upload
20
+ assert !File.exist?(file_path)
21
+ assert File.exist?(image_path)
22
+ assert File.exist?(image_path(:small))
23
+ medium.destroy
24
+ assert !File.exist?(image_path)
25
+ assert !File.exist?(image_path(:small))
26
+ end
27
+
28
+ test 'detroy attr' do
29
+ medium = Medium.create(local_attach: file_upload, destroy_attach: true)
30
+ assert File.exist?(file_path)
31
+ medium.update_attributes! destroy_local_attach: true
32
+ assert !File.exist?(file_path)
33
+ end
34
+
35
+ private
36
+
37
+ def month
38
+ Time.zone.now.month
39
+ end
40
+
41
+ def file_url(style=:original)
42
+ "/storage/text/11/#{style}/#{month}/file.txt"
43
+ end
44
+
45
+ def image_url(style=:original)
46
+ "/storage/image/5461/#{style}/#{month}/180x150.gif"
47
+ end
48
+
49
+ def file_path(style=:original)
50
+ Rails.root.join("public/storage/text/11/#{style}/#{month}/file.txt")
51
+ end
52
+
53
+ def image_path(style=:original)
54
+ Rails.root.join("public/storage/image/5461/#{style}/#{month}/180x150.gif")
55
+ end
56
+
57
+ end
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ class MagickToolTest < ActiveSupport::TestCase
4
+
5
+ teardown do
6
+ Dir[Rails.root.join('tmp', '*')].each do |file|
7
+ File.delete file
8
+ end
9
+ end
10
+
11
+ test 'force resize' do
12
+ Attachs::Tools::Magick.resize(source, :big_force, resized)
13
+ assert_equal [160,130], Attachs::Tools::Magick.dimensions(resized)
14
+ Attachs::Tools::Magick.resize(resized, :small_force)
15
+ assert_equal [140,110], Attachs::Tools::Magick.dimensions(resized)
16
+ end
17
+
18
+ test 'cover resize' do
19
+ Attachs::Tools::Magick.resize(source, :big_cover, resized)
20
+ assert_equal [160, 130], Attachs::Tools::Magick.dimensions(resized)
21
+ Attachs::Tools::Magick.resize(resized, :small_cover)
22
+ assert_equal [140,110], Attachs::Tools::Magick.dimensions(resized)
23
+ end
24
+
25
+ test 'contain resize' do
26
+ Attachs::Tools::Magick.resize(source, :big_contain, resized)
27
+ assert_equal [156, 130], Attachs::Tools::Magick.dimensions(resized)
28
+ Attachs::Tools::Magick.resize(resized, :small_contain)
29
+ assert_equal [132,110], Attachs::Tools::Magick.dimensions(resized)
30
+ end
31
+
32
+ private
33
+
34
+ def source
35
+ image_upload.path
36
+ end
37
+
38
+ def resized
39
+ Rails.root.join('public', 'resized.gif')
40
+ end
41
+
42
+ end
@@ -0,0 +1,65 @@
1
+ require 'test_helper'
2
+
3
+ class MigrationTest < ActiveSupport::TestCase
4
+
5
+ setup do
6
+ ActiveRecord::Migration.verbose = false
7
+ end
8
+
9
+ test 'table migration' do
10
+ table_migration.migrate(:up)
11
+ assert_includes columns, ['image_filename', :string]
12
+ assert_includes columns, ['image_size', :integer]
13
+ assert_includes columns, ['image_content_type', :string]
14
+ assert_includes columns, ['image_updated_at', :datetime]
15
+
16
+ assert_nothing_raised do
17
+ table_migration.migrate(:down)
18
+ end
19
+ end
20
+
21
+ test 'column migration' do
22
+ ActiveRecord::Base.connection.create_table :pictures
23
+
24
+ column_migration.migrate(:up)
25
+ assert_includes columns, ['image_filename', :string]
26
+ assert_includes columns, ['image_size', :integer]
27
+ assert_includes columns, ['image_content_type', :string]
28
+ assert_includes columns, ['image_updated_at', :datetime]
29
+
30
+ column_migration.migrate(:down)
31
+ refute_includes columns, ['image_filename', :string]
32
+ refute_includes columns, ['image_size', :integer]
33
+ refute_includes columns, ['image_content_type', :string]
34
+ refute_includes columns, ['image_updated_at', :datetime]
35
+ end
36
+
37
+ private
38
+
39
+ def columns
40
+ Picture.reset_column_information
41
+ Picture.columns.map { |column| [column.name, column.type] }
42
+ end
43
+
44
+ def table_migration
45
+ Class.new(ActiveRecord::Migration) do
46
+ def change
47
+ create_table :pictures do |t|
48
+ t.attachment :image
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def column_migration
55
+ Class.new(ActiveRecord::Migration) do
56
+ def up
57
+ add_attachment :pictures, :image
58
+ end
59
+ def down
60
+ remove_attachment :pictures, :image
61
+ end
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,56 @@
1
+ require 'test_helper'
2
+
3
+ class S3StorageTest < ActiveSupport::TestCase
4
+
5
+ test 'file url' do
6
+ medium = Medium.create(s3_attach: file_upload)
7
+ assert_equal file_url, medium.s3_attach.url
8
+ assert_equal file_url(ssl: true), medium.s3_attach.url(ssl: true)
9
+ end
10
+
11
+ test 'image url' do
12
+ medium = Medium.create(s3_attach: image_upload)
13
+ assert_equal image_url, medium.s3_attach.url
14
+ assert_equal image_url(ssl: true), medium.s3_attach.url(ssl: true)
15
+ assert_equal image_url(:small), medium.s3_attach.url(:small)
16
+ assert_equal image_url(:small, ssl: true), medium.s3_attach.url(:small, ssl: true)
17
+ end
18
+
19
+ test 'storage' do
20
+ medium = Medium.create(s3_attach: file_upload)
21
+ assert_url file_url
22
+ medium.update_attributes! s3_attach: image_upload
23
+ assert_not_url file_url
24
+ assert_url image_url
25
+ assert_url image_url(:small)
26
+ medium.destroy
27
+ assert_not_url image_url
28
+ assert_not_url image_url(:small)
29
+ end
30
+
31
+ test 'detroy attr' do
32
+ medium = Medium.create(s3_attach: file_upload, destroy_s3_attach: true)
33
+ assert_url file_url
34
+ medium.update_attributes! destroy_s3_attach: true
35
+ assert_not_url file_url
36
+ end
37
+
38
+ private
39
+
40
+ def month
41
+ Time.zone.now.month
42
+ end
43
+
44
+ def file_url(*args)
45
+ options = args.extract_options!
46
+ style = (args.first || :original)
47
+ "http#{'s' if options[:ssl]}://attachs-test.s3.amazonaws.com/storage/text/11/#{style}/#{month}/file.txt"
48
+ end
49
+
50
+ def image_url(*args)
51
+ options = args.extract_options!
52
+ style = (args.first || :original)
53
+ "http#{'s' if options[:ssl]}://attachs-test.s3.amazonaws.com/storage/image/5461/#{style}/#{month}/180x150.gif"
54
+ end
55
+
56
+ end
@@ -0,0 +1,61 @@
1
+ require 'test_helper'
2
+ require 'rake'
3
+
4
+ class TasksTest < ActiveSupport::TestCase
5
+
6
+ setup do
7
+ Dummy::Application.load_tasks
8
+ end
9
+
10
+ test 'refresh all styles' do
11
+ Medium.create(attach: image_upload)
12
+ original_small_time = small_time
13
+ original_big_time = big_time
14
+ ENV['CLASS'] = 'medium'
15
+ ENV['ATTACHMENT'] = 'attach'
16
+ sleep 1
17
+ Rake::Task['attachs:refresh:all'].invoke
18
+ assert File.file?(image_path(:small))
19
+ assert File.file?(image_path(:big))
20
+ assert_not_equal original_small_time, small_time
21
+ assert_not_equal original_big_time, big_time
22
+ end
23
+
24
+ test 'refersh missing styles' do
25
+ Medium.create(attach: image_upload)
26
+ original_big_time = big_time
27
+ original_small_time = small_time
28
+ File.delete image_path(:small)
29
+ ENV['CLASS'] = 'medium'
30
+ ENV['ATTACHMENT'] = 'attach'
31
+ sleep 1
32
+ Rake::Task['attachs:refresh:missing'].invoke
33
+ assert File.file?(image_path(:small))
34
+ assert File.file?(image_path(:big))
35
+ assert_not_equal original_small_time, small_time
36
+ assert_equal original_big_time, big_time
37
+ end
38
+
39
+ private
40
+
41
+ def image_path(style=:original)
42
+ Rails.root.join("public/#{style}/180x150.gif")
43
+ end
44
+
45
+ def small_path
46
+ image_path(:small)
47
+ end
48
+
49
+ def big_path
50
+ image_path(:big)
51
+ end
52
+
53
+ def small_time
54
+ File.mtime(small_path)
55
+ end
56
+
57
+ def big_time
58
+ File.mtime(big_path)
59
+ end
60
+
61
+ end
data/test/test_helper.rb CHANGED
@@ -22,28 +22,28 @@ load(File.expand_path('../dummy/db/schema.rb', __FILE__))
22
22
 
23
23
  # Addons
24
24
  class ActiveSupport::TestCase
25
- include ActionDispatch::TestProcess
26
-
27
- def load_s3
28
- require 'aws-sdk' unless defined?(AWS)
29
- @storage_type = Rails.application.config.attachs.storage
30
- Rails.application.config.attachs.storage = :s3
31
- Attachs::Storages::S3.config = YAML.load_file(Rails.root.join('config', 's3.yml')) if Attachs::Storages::S3.config.blank?
32
- self.class.teardown { Rails.application.config.attachs.storage = @storage_type }
25
+ include ActionView::Helpers::NumberHelper
26
+
27
+ private
28
+
29
+ def fixture_file_upload(path, content_type)
30
+ Rack::Test::UploadedFile.new(Rails.root.join("test/fixtures/#{path}"), content_type)
33
31
  end
34
32
 
35
- def fixture_file_upload_s3(fixture, type, path, default=false)
36
- upload = fixture_file_upload(fixture, type)
37
- storage = Attachs::Storages::S3.new(default, false)
38
- storage.store upload, path
33
+ def file_upload
34
+ fixture_file_upload('file.txt', 'text/plain')
39
35
  end
40
36
 
41
- def assert_object_s3(url)
42
- assert_equal '200', Net::HTTP.get_response(url).code
37
+ def image_upload
38
+ fixture_file_upload('180x150.gif', 'image/gif')
43
39
  end
44
40
 
45
- def assert_not_object_s3(url)
46
- assert_equal '403', Net::HTTP.get_response(url).code
41
+ def assert_url(url)
42
+ assert_equal '200', Net::HTTP.get_response(URI(url)).code
47
43
  end
48
- end
49
44
 
45
+ def assert_not_url(url)
46
+ assert_equal '403', Net::HTTP.get_response(URI(url)).code
47
+ end
48
+
49
+ end
@@ -0,0 +1,100 @@
1
+ require 'test_helper'
2
+
3
+ class ValidatorsTest < ActiveSupport::TestCase
4
+ include ActionView::Helpers::NumberHelper
5
+
6
+ test 'presence validator' do
7
+ model = build_model
8
+ model.validates_attachment_presence_of :attach
9
+ record = model.new
10
+ assert !record.valid?
11
+ message = I18n.t('errors.messages.attachment_presence')
12
+ assert record.errors[:attach].include?(message)
13
+
14
+ record = model.new(attach: image_upload)
15
+ assert record.valid?
16
+ assert record.errors[:attach].empty?
17
+ record.destroy
18
+ end
19
+
20
+ test 'content type regex validator' do
21
+ model = build_model
22
+ model.validates_attachment_content_type_of :attach, with: /\Aimage/
23
+ record = model.new(attach: file_upload)
24
+ assert !record.valid?
25
+ message = I18n.t('errors.messages.attachment_content_type_with')
26
+ assert record.errors[:attach].include?(message)
27
+
28
+ record = model.new(attach: image_upload)
29
+ assert record.valid?
30
+ assert record.errors[:attach].empty?
31
+ record.destroy
32
+ end
33
+
34
+ test 'content type inclusion validator' do
35
+ model = build_model
36
+ model.validates_attachment_content_type_of :attach, in: %w(image/gif)
37
+ record = model.new(attach: file_upload)
38
+ assert !record.valid?
39
+ message = I18n.t('errors.messages.attachment_content_type_in', types: %w(image/gif).to_sentence)
40
+ assert record.errors[:attach].include?(message)
41
+
42
+ record = model.new(attach: image_upload)
43
+ assert record.valid?
44
+ assert record.errors[:attach].empty?
45
+ record.destroy
46
+ end
47
+
48
+ test 'size range validator' do
49
+ model = build_model
50
+ model.validates_attachment_size_of :attach, in: 1..20.bytes
51
+ record = model.new(attach: image_upload)
52
+ assert !record.valid?
53
+ message = I18n.t('errors.messages.attachment_size_in', min: number_to_human_size(1.byte), max: number_to_human_size(20.bytes))
54
+ assert record.errors[:attach].include?(message)
55
+
56
+ record = model.new(attach: file_upload)
57
+ assert record.valid?
58
+ assert record.errors[:attach].empty?
59
+ record.destroy
60
+ end
61
+
62
+ test 'size minimum validator' do
63
+ model = build_model
64
+ model.validates_attachment_size_of :attach, less_than: 20.bytes
65
+ record = model.new(attach: image_upload)
66
+ assert !record.valid?
67
+ message = I18n.t('errors.messages.attachment_size_less_than', count: number_to_human_size(20.bytes))
68
+ assert record.errors[:attach].include?(message)
69
+
70
+ record = model.new(attach: file_upload)
71
+ assert record.valid?
72
+ assert record.errors[:attach].empty?
73
+ record.destroy
74
+ end
75
+
76
+ test 'size maximum validator' do
77
+ model = build_model
78
+ model.validates_attachment_size_of :attach, greater_than: 20.bytes
79
+ record = model.new(attach: file_upload)
80
+ assert !record.valid?
81
+ message = I18n.t('errors.messages.attachment_size_greater_than', count: number_to_human_size(20.bytes))
82
+ assert record.errors[:attach].include?(message)
83
+
84
+ record = model.new(attach: image_upload)
85
+ assert record.valid?
86
+ assert record.errors[:attach].empty?
87
+ record.destroy
88
+ end
89
+
90
+ private
91
+
92
+ def build_model
93
+ Class.new(Medium) do
94
+ def self.name
95
+ 'Medium'
96
+ end
97
+ end
98
+ end
99
+
100
+ end