attachy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3 -0
  3. data/LICENSE +21 -0
  4. data/README.md +108 -0
  5. data/lib/assets/javascripts/attachy.js +289 -0
  6. data/lib/attachy.rb +13 -0
  7. data/lib/attachy/builders/attachy/form_builder.rb +15 -0
  8. data/lib/attachy/engine.rb +16 -0
  9. data/lib/attachy/helpers/attachy/view_helper.rb +31 -0
  10. data/lib/attachy/models/attachy/extension.rb +79 -0
  11. data/lib/attachy/models/attachy/file.rb +59 -0
  12. data/lib/attachy/models/attachy/viewer.rb +170 -0
  13. data/lib/attachy/version.rb +3 -0
  14. data/lib/generators/attachy/install_generator.rb +25 -0
  15. data/lib/generators/attachy/templates/config/attachy.yml.erb +15 -0
  16. data/lib/generators/attachy/templates/db/migrate/create_attachy_files_table.rb +19 -0
  17. data/lib/generators/attachy/templates/public/cloudinary_cors.html +46 -0
  18. data/spec/builders/attachy/form_builder/attachy_content_spec.rb +35 -0
  19. data/spec/builders/attachy/form_builder/attachy_file_field_spec.rb +23 -0
  20. data/spec/builders/attachy/form_builder/attachy_spec.rb +35 -0
  21. data/spec/factories/attachy/file.rb +12 -0
  22. data/spec/factories/user.rb +5 -0
  23. data/spec/helpers/attachy/attachy_content_spec.rb +21 -0
  24. data/spec/helpers/attachy/attachy_file_field_spec.rb +21 -0
  25. data/spec/helpers/attachy/attachy_spec.rb +35 -0
  26. data/spec/models/attachy/callback/destroy_file_spec.rb +55 -0
  27. data/spec/models/attachy/callback/remove_tmp_tag_spec.rb +11 -0
  28. data/spec/models/attachy/extension/user/avatar_spec.rb +91 -0
  29. data/spec/models/attachy/extension/user/photos_spec.rb +88 -0
  30. data/spec/models/attachy/file/config_spec.rb +11 -0
  31. data/spec/models/attachy/file/default_spec.rb +26 -0
  32. data/spec/models/attachy/file/path_spec.rb +16 -0
  33. data/spec/models/attachy/file/transform_spec.rb +86 -0
  34. data/spec/models/attachy/file_spec.rb +14 -0
  35. data/spec/models/attachy/viewer/attachments_spec.rb +28 -0
  36. data/spec/models/attachy/viewer/button_label_options_spec.rb +15 -0
  37. data/spec/models/attachy/viewer/button_label_spec.rb +34 -0
  38. data/spec/models/attachy/viewer/content_options_spec.rb +29 -0
  39. data/spec/models/attachy/viewer/content_spec.rb +62 -0
  40. data/spec/models/attachy/viewer/field_options_spec.rb +18 -0
  41. data/spec/models/attachy/viewer/field_spec.rb +56 -0
  42. data/spec/models/attachy/viewer/file_button_options_spec.rb +18 -0
  43. data/spec/models/attachy/viewer/file_button_spec.rb +57 -0
  44. data/spec/models/attachy/viewer/file_field_options_spec.rb +90 -0
  45. data/spec/models/attachy/viewer/file_field_spec.rb +25 -0
  46. data/spec/models/attachy/viewer/hidden_field_spec.rb +22 -0
  47. data/spec/models/attachy/viewer/image_spec.rb +170 -0
  48. data/spec/models/attachy/viewer/link_options_spec.rb +18 -0
  49. data/spec/models/attachy/viewer/link_spec.rb +131 -0
  50. data/spec/models/attachy/viewer/node_options_spec.rb +18 -0
  51. data/spec/models/attachy/viewer/node_spec.rb +134 -0
  52. data/spec/models/attachy/viewer/nodes_spec.rb +21 -0
  53. data/spec/models/attachy/viewer/remove_button_options_spec.rb +18 -0
  54. data/spec/models/attachy/viewer/transform_spec.rb +44 -0
  55. data/spec/models/attachy/viewer/value_spec.rb +83 -0
  56. data/spec/models/user_spec.rb +9 -0
  57. data/spec/rails_helper.rb +11 -0
  58. data/spec/support/common.rb +20 -0
  59. data/spec/support/database_cleaner.rb +19 -0
  60. data/spec/support/db/migrate/create_users_table.rb +7 -0
  61. data/spec/support/factory_girl.rb +7 -0
  62. data/spec/support/html_matchers.rb +5 -0
  63. data/spec/support/migrate.rb +4 -0
  64. data/spec/support/models/user.rb +5 -0
  65. data/spec/support/shoulda.rb +8 -0
  66. metadata +365 -0
@@ -0,0 +1,90 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Attachy::Viewer, '.file_field_options' do
4
+ let!(:object) { create :user }
5
+ let!(:method) { :avatar }
6
+
7
+ let!(:file) do
8
+ allow(Cloudinary::Uploader).to receive(:remove_tag)
9
+
10
+ create :file, attachable: object, scope: method
11
+ end
12
+
13
+ subject { described_class.new method, object }
14
+
15
+ context 'when :accept has invalid mime type' do
16
+ context 'with one type' do
17
+ before do
18
+ allow(subject).to receive(:metadata) { { accept: :abc } }
19
+ end
20
+
21
+ it 'does not added as attribute' do
22
+ el = subject.file_field_options
23
+
24
+ expect(el).to eq(class: :attachy__fileupload)
25
+ end
26
+ end
27
+
28
+ context 'with more than one type' do
29
+ before do
30
+ allow(subject).to receive(:metadata) { { accept: [:abc, :png] } }
31
+ end
32
+
33
+ it 'is added as attribute only the valid one' do
34
+ el = subject.file_field_options
35
+
36
+ expect(el).to eq(accept: 'image/png', class: :attachy__fileupload)
37
+ end
38
+ end
39
+ end
40
+
41
+ context 'when :accept is a valid mime type' do
42
+ context 'with one type' do
43
+ before do
44
+ allow(subject).to receive(:metadata) { { accept: :jpg } }
45
+ end
46
+
47
+ it 'is added as attribute' do
48
+ el = subject.file_field_options
49
+
50
+ expect(el).to eq(accept: 'image/jpeg', class: :attachy__fileupload)
51
+ end
52
+ end
53
+
54
+ context 'with more than one type' do
55
+ before do
56
+ allow(subject).to receive(:metadata) { { accept: [:jpg, :png] } }
57
+ end
58
+
59
+ it 'is added as attribute' do
60
+ el = subject.file_field_options
61
+
62
+ expect(el).to eq(accept: 'image/jpeg,image/png', class: :attachy__fileupload)
63
+ end
64
+ end
65
+ end
66
+
67
+ context 'when :multiple is true' do
68
+ before do
69
+ allow(subject).to receive(:metadata) { { multiple: true } }
70
+ end
71
+
72
+ it 'turns the field multiple' do
73
+ el = subject.file_field_options
74
+
75
+ expect(el).to eq(multiple: true, class: :attachy__fileupload)
76
+ end
77
+ end
78
+
79
+ context 'when :multiple is false' do
80
+ before do
81
+ allow(subject).to receive(:metadata) { { multiple: false } }
82
+ end
83
+
84
+ it 'does not adds the multiple attribute' do
85
+ el = subject.file_field_options
86
+
87
+ expect(el).to eq(class: :attachy__fileupload)
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,25 @@
1
+ require 'rails_helper'
2
+ require 'cloudinary'
3
+
4
+ RSpec.describe Attachy::Viewer, '.file_field' do
5
+ let!(:method) { :avatar }
6
+ let!(:object) { create :user }
7
+ let!(:options) { {} }
8
+ let!(:view) { double }
9
+
10
+ let!(:file) do
11
+ allow(Cloudinary::Uploader).to receive(:remove_tag)
12
+
13
+ create :file, attachable: object, scope: method
14
+ end
15
+
16
+ before { allow(subject).to receive(:file_field_options) { { key: :value } } }
17
+
18
+ subject { described_class.new method, object, options, view }
19
+
20
+ it 'returns the hidden field with attachments value' do
21
+ allow(view).to receive(:cl_image_upload_tag).with(method, html: subject.file_field_options, tags: [Attachy::ENV_TAG, Attachy::TMP_TAG]) { :input }
22
+
23
+ expect(subject.file_field).to eq :input
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Attachy::Viewer, '.hidden_field' do
4
+ let!(:object) { create :user }
5
+ let!(:method) { :avatar }
6
+
7
+ let!(:file) do
8
+ allow(Cloudinary::Uploader).to receive(:remove_tag)
9
+
10
+ create :file, attachable: object, scope: method
11
+ end
12
+
13
+ before { allow(subject).to receive(:value) { :value } }
14
+
15
+ subject { described_class.new method, object }
16
+
17
+ it 'returns the hidden field with attachments value' do
18
+ el = subject.hidden_field
19
+
20
+ expect(el).to have_tag :input, with: { name: 'user[avatar]', type: 'hidden', value: 'value' }
21
+ end
22
+ end
@@ -0,0 +1,170 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Attachy::Viewer, '.image' do
4
+ let!(:method) { :avatar }
5
+ let!(:object) { create :user }
6
+ let!(:viewer) { described_class.new method, object, options }
7
+ let!(:default_html) { { alt: :image, height: 50, width: 150 } }
8
+ let!(:default_t) { { height: 100, width: 200 } }
9
+ let!(:options) { { t: default_t, html: default_html } }
10
+
11
+ let!(:file) do
12
+ allow(Cloudinary::Uploader).to receive(:remove_tag)
13
+
14
+ create :file, attachable: object
15
+ end
16
+
17
+ context 'when :html is present' do
18
+ let!(:html_attributes) { { alt: :alt, invalid: :invalid, height: 11, width: 22 } }
19
+
20
+ context 'and :t is blank' do
21
+ let!(:t_attributes) { {} }
22
+
23
+ before do
24
+ allow_any_instance_of(Attachy::File).to receive(:url).with(t_attributes) { 'http://example.org' }
25
+ end
26
+
27
+ it 'adds all attributes on image' do
28
+ el = viewer.image(t: t_attributes, html: html_attributes)
29
+
30
+ expect(el).to have_tag 'img', with: html_attributes
31
+ end
32
+ end
33
+
34
+ context 'and :t is present' do
35
+ let!(:t_attributes) { { height: 1, width: 2 } }
36
+
37
+ before { allow_any_instance_of(Attachy::File).to receive(:url).with(t_attributes) { 'http://example.org' } }
38
+
39
+ it 'gives priority to :html' do
40
+ el = viewer.image(t: t_attributes, html: html_attributes)
41
+
42
+ expect(el).to have_tag 'img', with: html_attributes
43
+ end
44
+ end
45
+
46
+ context 'and :t is not given' do
47
+ before { allow_any_instance_of(Attachy::File).to receive(:url).with(default_t) { 'http://example.org' } }
48
+
49
+ it 'uses the :html attributes and transform with default :t' do
50
+ el = viewer.image(html: html_attributes)
51
+
52
+ expect(el).to have_tag 'img', with: {
53
+ 'data-crop' => 'fill',
54
+ 'data-format' => file.format,
55
+ 'data-height' => 100,
56
+ 'data-secure' => true,
57
+ 'data-sign-url' => true,
58
+ 'data-version' => file.version,
59
+ 'data-width' => 200,
60
+ alt: 'alt',
61
+ height: 11,
62
+ invalid: 'invalid',
63
+ src: 'http://example.org',
64
+ width: 22
65
+ }
66
+ end
67
+ end
68
+ end
69
+
70
+ context 'when :html is blank' do
71
+ let!(:html_attributes) { {} }
72
+
73
+ context 'and :t is blank' do
74
+ let!(:t_attributes) { {} }
75
+
76
+ before { allow_any_instance_of(Attachy::File).to receive(:url).with(t_attributes) { 'http://example.org' } }
77
+
78
+ it 'adds only the default transformation with file attributes' do
79
+ el = viewer.image(t: t_attributes, html: html_attributes)
80
+
81
+ expect(el).to have_tag 'img', with: {
82
+ 'data-format' => file.format,
83
+ 'data-secure' => true,
84
+ 'data-sign-url' => true,
85
+ 'data-version' => file.version
86
+ }
87
+ end
88
+ end
89
+
90
+ context 'and :t is present' do
91
+ let!(:t_attributes) { { height: 1, width: 2 } }
92
+
93
+ before { allow_any_instance_of(Attachy::File).to receive(:url).with(t_attributes) { 'http://example.org' } }
94
+
95
+ it 'adds the :t attributes on html attributes with default data' do
96
+ el = viewer.image(t: t_attributes, html: html_attributes)
97
+
98
+ expect(el).to have_tag 'img', with: {
99
+ 'data-format' => file.format,
100
+ 'data-public-id' => file.public_id,
101
+ 'data-secure' => true,
102
+ 'data-sign-url' => true,
103
+ 'data-version' => file.version,
104
+ height: 1,
105
+ width: 2
106
+ }
107
+ end
108
+ end
109
+ end
110
+
111
+ context 'when :html is not given' do
112
+ context 'and :t is not given' do
113
+ before { allow_any_instance_of(Attachy::File).to receive(:url).with(default_t) { 'http://example.org' } }
114
+
115
+ it 'uses the default :html with default :t' do
116
+ el = viewer.image
117
+
118
+ expect(el).to have_tag 'img', with: {
119
+ 'alt' => 'Example',
120
+ 'data-crop' => 'fill',
121
+ 'data-format' => file.format,
122
+ 'data-height' => 100,
123
+ 'data-public-id' => file.public_id,
124
+ 'data-secure' => true,
125
+ 'data-sign-url' => true,
126
+ 'data-version' => file.version,
127
+ 'data-width' => 200,
128
+ 'height' => 100,
129
+ 'src' => 'http://example.org',
130
+ 'width' => 200
131
+ }
132
+ end
133
+ end
134
+
135
+ context 'but :t is given' do
136
+ let!(:t_attributes) { { height: 1, width: 2 } }
137
+
138
+ before { allow_any_instance_of(Attachy::File).to receive(:url).with(t_attributes) { 'http://example.org' } }
139
+
140
+ it 'uses the default :html with given :t overriding the default :t' do
141
+ el = viewer.image(t: t_attributes)
142
+
143
+ expect(el).to have_tag 'img', with: {
144
+ 'alt' => 'Example',
145
+ 'data-crop' => 'fill',
146
+ 'data-format' => file.format,
147
+ 'data-height' => 1,
148
+ 'data-public-id' => file.public_id,
149
+ 'data-secure' => true,
150
+ 'data-sign-url' => true,
151
+ 'data-version' => file.version,
152
+ 'data-width' => 2,
153
+ 'height' => 1,
154
+ 'src' => 'http://example.org',
155
+ 'width' => 2
156
+ }
157
+ end
158
+ end
159
+ end
160
+
161
+ context 'when given a :file' do
162
+ let!(:file) { build :file, format: :png, version: 7 }
163
+
164
+ it 'is used' do
165
+ expect(file).to receive(:url).with(default_t) { 'http://example.org' }
166
+
167
+ viewer.image file
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,18 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Attachy::Viewer, '.link_options' do
4
+ let!(:object) { create :user }
5
+ let!(:method) { :avatar }
6
+
7
+ let!(:file) do
8
+ allow(Cloudinary::Uploader).to receive(:remove_tag)
9
+
10
+ create :file, attachable: object, scope: method
11
+ end
12
+
13
+ subject { described_class.new method, object }
14
+
15
+ it 'returns the default link options' do
16
+ expect(subject.link_options).to eq(class: :attachy__link)
17
+ end
18
+ end
@@ -0,0 +1,131 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Attachy::Viewer, '.link' do
4
+ let!(:method) { :avatar }
5
+ let!(:object) { create :user }
6
+ let!(:default_html) { { alt: :image, height: 50, width: 150 } }
7
+ let!(:default_t) { { height: 100, width: 200 } }
8
+ let!(:options) { { t: default_t, html: default_html } }
9
+
10
+ let!(:file) do
11
+ allow(Cloudinary::Uploader).to receive(:remove_tag)
12
+
13
+ create :file, attachable: object
14
+ end
15
+
16
+ subject { described_class.new method, object, options }
17
+
18
+ describe 'default options' do
19
+ before do
20
+ allow_any_instance_of(Attachy::File).to receive(:url).with(crop: :none) { 'http://example.org' }
21
+ end
22
+
23
+ it 'adds the link options' do
24
+ expect(subject).to receive(:image).with(file, t: default_t) { :image }
25
+
26
+ el = subject.link
27
+
28
+ expect(el).to have_tag :a, with: { class: 'attachy__link' }
29
+ end
30
+ end
31
+
32
+ context 'when :t is not given' do
33
+ before { allow_any_instance_of(Attachy::File).to receive(:url) { 'http://example.org' } }
34
+
35
+ it 'builds the imagem with generic transform' do
36
+ expect(subject).to receive(:image).with(file, t: default_t) { :image }
37
+
38
+ el = subject.link
39
+
40
+ expect(el).to have_tag :a do
41
+ with_text 'image'
42
+ end
43
+ end
44
+ end
45
+
46
+ context 'when :t is given' do
47
+ let!(:t) { { height: 7, width: 17 } }
48
+
49
+ before { allow_any_instance_of(Attachy::File).to receive(:url) { 'http://example.org' } }
50
+
51
+ it 'builds the imagem with given transform' do
52
+ expect(subject).to receive(:image).with(file, t: t) { :image }
53
+
54
+ el = subject.link(t: t)
55
+
56
+ expect(el).to have_tag :a do
57
+ with_text 'image'
58
+ end
59
+ end
60
+ end
61
+
62
+ context 'when :t is not given' do
63
+ before { allow_any_instance_of(Attachy::File).to receive(:url).with(crop: :none) { 'http://example.org' } }
64
+
65
+ it 'builds the link url with :crop :none' do
66
+ expect(subject).to receive(:image).with(file, t: default_t) { :image }
67
+
68
+ el = subject.link
69
+
70
+ expect(el).to have_tag :a, with: { href: 'http://example.org' }
71
+ end
72
+
73
+ it 'adds it on data attributes' do
74
+ expect(subject).to receive(:image).with(file, t: default_t) { :image }
75
+
76
+ el = subject.link
77
+
78
+ expect(el).to have_tag :a, with: { 'data-crop' => 'none' }
79
+ end
80
+ end
81
+
82
+ context 'when :tl is given' do
83
+ let!(:tl) { { height: 4, width: 8 } }
84
+
85
+ before { allow_any_instance_of(Attachy::File).to receive(:url).with(tl) { 'http://example.org' } }
86
+
87
+ it 'builds the link url with given transform' do
88
+ expect(subject).to receive(:image).with(file, t: default_t) { :image }
89
+
90
+ el = subject.link(tl: tl)
91
+
92
+ expect(el).to have_tag :a, with: { href: 'http://example.org' }
93
+ end
94
+ end
95
+
96
+ context 'when :html is present' do
97
+ let!(:html) { { invalid: :invalid, target: :blank } }
98
+
99
+ before { allow_any_instance_of(Attachy::File).to receive(:url) { 'http://example.org' } }
100
+
101
+ it 'is added to html attributes' do
102
+ allow(subject).to receive(:image) { :image }
103
+
104
+ el = subject.link(html: html)
105
+
106
+ expect(el).to have_tag 'a', with: { invalid: 'invalid', target: 'blank' }
107
+ end
108
+ end
109
+
110
+ context 'when given a :file' do
111
+ let!(:file) { build :file }
112
+
113
+ it 'is used' do
114
+ expect(file).to receive(:url).twice { 'http://example.org' }
115
+
116
+ subject.link file
117
+ end
118
+ end
119
+
120
+ context 'when a block is given' do
121
+ let!(:html) { { target: :blank } }
122
+ let!(:tl) { { width: 10 } }
123
+
124
+ it 'yields the :html and :attachments' do
125
+ subject.link(tl: tl, html: html) do |htm, attachments|
126
+ expect(attachments).to eq [file]
127
+ expect(htm).to eq(data: { width: 10 }, target: :blank, class: :attachy__link)
128
+ end
129
+ end
130
+ end
131
+ end