attachs 0.3.5 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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