attachy 0.1.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 (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