attachy 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/LICENSE +21 -0
- data/README.md +108 -0
- data/lib/assets/javascripts/attachy.js +289 -0
- data/lib/attachy.rb +13 -0
- data/lib/attachy/builders/attachy/form_builder.rb +15 -0
- data/lib/attachy/engine.rb +16 -0
- data/lib/attachy/helpers/attachy/view_helper.rb +31 -0
- data/lib/attachy/models/attachy/extension.rb +79 -0
- data/lib/attachy/models/attachy/file.rb +59 -0
- data/lib/attachy/models/attachy/viewer.rb +170 -0
- data/lib/attachy/version.rb +3 -0
- data/lib/generators/attachy/install_generator.rb +25 -0
- data/lib/generators/attachy/templates/config/attachy.yml.erb +15 -0
- data/lib/generators/attachy/templates/db/migrate/create_attachy_files_table.rb +19 -0
- data/lib/generators/attachy/templates/public/cloudinary_cors.html +46 -0
- data/spec/builders/attachy/form_builder/attachy_content_spec.rb +35 -0
- data/spec/builders/attachy/form_builder/attachy_file_field_spec.rb +23 -0
- data/spec/builders/attachy/form_builder/attachy_spec.rb +35 -0
- data/spec/factories/attachy/file.rb +12 -0
- data/spec/factories/user.rb +5 -0
- data/spec/helpers/attachy/attachy_content_spec.rb +21 -0
- data/spec/helpers/attachy/attachy_file_field_spec.rb +21 -0
- data/spec/helpers/attachy/attachy_spec.rb +35 -0
- data/spec/models/attachy/callback/destroy_file_spec.rb +55 -0
- data/spec/models/attachy/callback/remove_tmp_tag_spec.rb +11 -0
- data/spec/models/attachy/extension/user/avatar_spec.rb +91 -0
- data/spec/models/attachy/extension/user/photos_spec.rb +88 -0
- data/spec/models/attachy/file/config_spec.rb +11 -0
- data/spec/models/attachy/file/default_spec.rb +26 -0
- data/spec/models/attachy/file/path_spec.rb +16 -0
- data/spec/models/attachy/file/transform_spec.rb +86 -0
- data/spec/models/attachy/file_spec.rb +14 -0
- data/spec/models/attachy/viewer/attachments_spec.rb +28 -0
- data/spec/models/attachy/viewer/button_label_options_spec.rb +15 -0
- data/spec/models/attachy/viewer/button_label_spec.rb +34 -0
- data/spec/models/attachy/viewer/content_options_spec.rb +29 -0
- data/spec/models/attachy/viewer/content_spec.rb +62 -0
- data/spec/models/attachy/viewer/field_options_spec.rb +18 -0
- data/spec/models/attachy/viewer/field_spec.rb +56 -0
- data/spec/models/attachy/viewer/file_button_options_spec.rb +18 -0
- data/spec/models/attachy/viewer/file_button_spec.rb +57 -0
- data/spec/models/attachy/viewer/file_field_options_spec.rb +90 -0
- data/spec/models/attachy/viewer/file_field_spec.rb +25 -0
- data/spec/models/attachy/viewer/hidden_field_spec.rb +22 -0
- data/spec/models/attachy/viewer/image_spec.rb +170 -0
- data/spec/models/attachy/viewer/link_options_spec.rb +18 -0
- data/spec/models/attachy/viewer/link_spec.rb +131 -0
- data/spec/models/attachy/viewer/node_options_spec.rb +18 -0
- data/spec/models/attachy/viewer/node_spec.rb +134 -0
- data/spec/models/attachy/viewer/nodes_spec.rb +21 -0
- data/spec/models/attachy/viewer/remove_button_options_spec.rb +18 -0
- data/spec/models/attachy/viewer/transform_spec.rb +44 -0
- data/spec/models/attachy/viewer/value_spec.rb +83 -0
- data/spec/models/user_spec.rb +9 -0
- data/spec/rails_helper.rb +11 -0
- data/spec/support/common.rb +20 -0
- data/spec/support/database_cleaner.rb +19 -0
- data/spec/support/db/migrate/create_users_table.rb +7 -0
- data/spec/support/factory_girl.rb +7 -0
- data/spec/support/html_matchers.rb +5 -0
- data/spec/support/migrate.rb +4 -0
- data/spec/support/models/user.rb +5 -0
- data/spec/support/shoulda.rb +8 -0
- metadata +365 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
<!DOCTYPE HTML>
|
2
|
+
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta charset="utf-8">
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<script>
|
9
|
+
/*
|
10
|
+
json2.js
|
11
|
+
2016-10-28
|
12
|
+
|
13
|
+
Public Domain.
|
14
|
+
|
15
|
+
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
16
|
+
|
17
|
+
See http://www.JSON.org/js.html
|
18
|
+
This code should be minified before deployment.
|
19
|
+
|
20
|
+
See http://javascript.crockford.com/jsmin.html
|
21
|
+
|
22
|
+
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
23
|
+
NOT CONTROL.
|
24
|
+
*/
|
25
|
+
|
26
|
+
"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(a){return a<10?"0"+a:a}function this_value(){return this.valueOf()}function quote(a){return rx_escapable.lastIndex=0,rx_escapable.test(a)?'"'+a.replace(rx_escapable,function(a){var b=meta[a];return"string"==typeof b?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,h,g=gap,i=b[a];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(a)),"function"==typeof rep&&(i=rep.call(b,a,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,h=[],"[object Array]"===Object.prototype.toString.apply(i)){for(f=i.length,c=0;c<f;c+=1)h[c]=str(c,i)||"null";return e=0===h.length?"[]":gap?"[\n"+gap+h.join(",\n"+gap)+"\n"+g+"]":"["+h.join(",")+"]",gap=g,e}if(rep&&"object"==typeof rep)for(f=rep.length,c=0;c<f;c+=1)"string"==typeof rep[c]&&(d=rep[c],e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));else for(d in i)Object.prototype.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));return e=0===h.length?"{}":gap?"{\n"+gap+h.join(",\n"+gap)+"\n"+g+"}":"{"+h.join(",")+"}",gap=g,e}}var rx_one=/^[\],:{}\s]*$/,rx_two=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,rx_three=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,rx_four=/(?:^|:|,)(?:\s*\[)+/g,rx_escapable=/[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,rx_dangerous=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},Boolean.prototype.toJSON=this_value,Number.prototype.toJSON=this_value,String.prototype.toJSON=this_value);var gap,indent,meta,rep;"function"!=typeof JSON.stringify&&(meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(a,b,c){var d;if(gap="",indent="","number"==typeof c)for(d=0;d<c;d+=1)indent+=" ";else"string"==typeof c&&(indent=c);if(rep=b,b&&"function"!=typeof b&&("object"!=typeof b||"number"!=typeof b.length))throw new Error("JSON.stringify");return str("",{"":a})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&"object"==typeof e)for(c in e)Object.prototype.hasOwnProperty.call(e,c)&&(d=walk(e,c),void 0!==d?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;if(text=String(text),rx_dangerous.lastIndex=0,rx_dangerous.test(text)&&(text=text.replace(rx_dangerous,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})),rx_one.test(text.replace(rx_two,"@").replace(rx_three,"]").replace(rx_four,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}();
|
27
|
+
/* end of json2.js */
|
28
|
+
|
29
|
+
function parse(query) {
|
30
|
+
var
|
31
|
+
result = {},
|
32
|
+
params = query.split('&');
|
33
|
+
|
34
|
+
for (var i = 0; i < params.length; i++) {
|
35
|
+
var param = params[i].split('=');
|
36
|
+
|
37
|
+
result[param[0]] = decodeURIComponent(param[1]);
|
38
|
+
}
|
39
|
+
|
40
|
+
return JSON.stringify(result);
|
41
|
+
}
|
42
|
+
|
43
|
+
document.body.textContent = document.body.innerText = parse(window.location.search.slice(1));
|
44
|
+
</script>
|
45
|
+
</body>
|
46
|
+
</html>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
class Dummy < ActionView::Helpers::FormBuilder
|
4
|
+
include Attachy::FormBuilder
|
5
|
+
end
|
6
|
+
|
7
|
+
class DummyHelper
|
8
|
+
include Attachy::ViewHelper
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec.describe Dummy, '.attachy_content' do
|
12
|
+
let!(:method) { :avatar }
|
13
|
+
let!(:options) { { key: :value } }
|
14
|
+
let!(:object) { create :user }
|
15
|
+
let!(:template) { DummyHelper.new }
|
16
|
+
let!(:dummy) { described_class.new method, object, template, options }
|
17
|
+
|
18
|
+
context 'with no block' do
|
19
|
+
xit 'delegates to view helper' do
|
20
|
+
expect(template).to receive(:attachy_content).with(method, object, options, nil)
|
21
|
+
|
22
|
+
dummy.attachy_content method, options
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with block' do
|
27
|
+
let!(:block) { proc {} }
|
28
|
+
|
29
|
+
xit 'delegates to view helper with block' do
|
30
|
+
expect(template).to receive(:attachy_content).with(method, object, options, block)
|
31
|
+
|
32
|
+
dummy.attachy_content method, options, &block
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
class Dummy < ActionView::Helpers::FormBuilder
|
4
|
+
include Attachy::FormBuilder
|
5
|
+
end
|
6
|
+
|
7
|
+
class DummyHelper
|
8
|
+
include Attachy::ViewHelper
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec.describe Dummy, '.attachy_file_field' do
|
12
|
+
let!(:method) { :avatar }
|
13
|
+
let!(:options) { { key: :value } }
|
14
|
+
let!(:object) { create :user }
|
15
|
+
let!(:template) { DummyHelper.new }
|
16
|
+
let!(:dummy) { described_class.new method, object, template, options }
|
17
|
+
|
18
|
+
it 'delegates to view helper' do
|
19
|
+
expect(template).to receive(:attachy_file_field).with(method, object, options)
|
20
|
+
|
21
|
+
dummy.attachy_file_field method, options
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
class Dummy < ActionView::Helpers::FormBuilder
|
4
|
+
include Attachy::FormBuilder
|
5
|
+
end
|
6
|
+
|
7
|
+
class DummyHelper
|
8
|
+
include Attachy::ViewHelper
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec.describe Dummy, '.attachy' do
|
12
|
+
let!(:method) { :avatar }
|
13
|
+
let!(:options) { { key: :value } }
|
14
|
+
let!(:object) { create :user }
|
15
|
+
let!(:template) { DummyHelper.new }
|
16
|
+
let!(:dummy) { described_class.new method, object, template, options }
|
17
|
+
|
18
|
+
context 'with no block' do
|
19
|
+
it 'delegates to view helper' do
|
20
|
+
expect(template).to receive(:attachy).with(method, object, options, nil)
|
21
|
+
|
22
|
+
dummy.attachy method, options
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with block' do
|
27
|
+
let!(:block) { proc {} }
|
28
|
+
|
29
|
+
it 'delegates to view helper with block' do
|
30
|
+
expect(template).to receive(:attachy).with(method, object, options, block)
|
31
|
+
|
32
|
+
dummy.attachy method, options, &block
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
class DummyHelper
|
4
|
+
include Attachy::ViewHelper
|
5
|
+
end
|
6
|
+
|
7
|
+
RSpec.describe DummyHelper, '.attachy_content' do
|
8
|
+
let!(:method) { :avatar }
|
9
|
+
let!(:options) { { key: :value } }
|
10
|
+
let!(:object) { create :user }
|
11
|
+
let!(:helper) { DummyHelper.new }
|
12
|
+
let!(:viewer) { double Attachy::Viewer, content: :content }
|
13
|
+
|
14
|
+
before do
|
15
|
+
allow(Attachy::Viewer).to receive(:new).with(method, object, options, helper) { viewer }
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'calls content from viewer' do
|
19
|
+
expect(helper.attachy_content(method, object, options)).to eq :content
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
class DummyHelper
|
4
|
+
include Attachy::ViewHelper
|
5
|
+
end
|
6
|
+
|
7
|
+
RSpec.describe DummyHelper, '.attachy_file_field' do
|
8
|
+
let!(:method) { :avatar }
|
9
|
+
let!(:options) { { key: :value } }
|
10
|
+
let!(:object) { create :user }
|
11
|
+
let!(:helper) { DummyHelper.new }
|
12
|
+
let!(:viewer) { double Attachy::Viewer, file_field: :file_field }
|
13
|
+
|
14
|
+
before do
|
15
|
+
allow(Attachy::Viewer).to receive(:new).with(method, object, options, helper) { viewer }
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'calls file_field from viewer' do
|
19
|
+
expect(helper.attachy_file_field(method, object, options)).to eq :file_field
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
class DummyHelper
|
4
|
+
include Attachy::ViewHelper
|
5
|
+
end
|
6
|
+
|
7
|
+
RSpec.describe DummyHelper, '.attachy' do
|
8
|
+
let!(:method) { :avatar }
|
9
|
+
let!(:options) { { key: :value } }
|
10
|
+
let!(:object) { create :user }
|
11
|
+
let!(:helper) { DummyHelper.new }
|
12
|
+
let!(:viewer) { double Attachy::Viewer, field: :field }
|
13
|
+
|
14
|
+
context 'with no block' do
|
15
|
+
before do
|
16
|
+
allow(Attachy::Viewer).to receive(:new).with(method, object, options, helper) { viewer }
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'calls field from viewer' do
|
20
|
+
expect(helper.attachy(method, object, options, nil)).to eq :field
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with block' do
|
25
|
+
let!(:block) { proc { |v| expect(v.field).to eq :field } }
|
26
|
+
|
27
|
+
before do
|
28
|
+
allow(Attachy::Viewer).to receive(:new).with(method, object, options, helper) { viewer }
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'delegates to view helper with block' do
|
32
|
+
helper.attachy method, object, options, block
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe User, ':destroy_file' do
|
4
|
+
let!(:user) { create :user }
|
5
|
+
|
6
|
+
let!(:photo) do
|
7
|
+
expect(Cloudinary::Uploader).to receive(:remove_tag)
|
8
|
+
|
9
|
+
create :file, public_id: 'public_id', scope: :photos, attachable: user
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'via assign' do
|
13
|
+
context 'via assign on relation' do
|
14
|
+
it 'removes the file via api' do
|
15
|
+
expect(Cloudinary::Uploader).to receive(:destroy).with('public_id')
|
16
|
+
|
17
|
+
user.photos_files = []
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'via assign on scope' do
|
22
|
+
it 'removes the file via api' do
|
23
|
+
expect(Cloudinary::Uploader).to receive(:destroy).with('public_id')
|
24
|
+
|
25
|
+
user.photos = '[]'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'via method' do
|
31
|
+
context 'via method over one record' do
|
32
|
+
it 'removes the file via api' do
|
33
|
+
expect(Cloudinary::Uploader).to receive(:destroy).with('public_id')
|
34
|
+
|
35
|
+
user.photos_files.first.destroy
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'via method over criteria' do
|
40
|
+
it 'removes the file via api' do
|
41
|
+
expect(Cloudinary::Uploader).to receive(:destroy).with('public_id')
|
42
|
+
|
43
|
+
user.photos_files.destroy_all
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'via .clear' do
|
48
|
+
it 'does not removes the file via api' do
|
49
|
+
expect(Cloudinary::Uploader).not_to receive(:destroy)
|
50
|
+
|
51
|
+
user.photos_files.clear
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe User, ':remove_tmp_tag' do
|
4
|
+
let!(:user) { create :user }
|
5
|
+
|
6
|
+
it 'removes the tmp tag via api' do
|
7
|
+
expect(Cloudinary::Uploader).to receive(:remove_tag).with(Attachy::TMP_TAG, ['public_id'])
|
8
|
+
|
9
|
+
create :file, public_id: 'public_id', attachable: user
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe User, ':avatar' do
|
4
|
+
before do
|
5
|
+
allow(Cloudinary::Uploader).to receive(:remove_tag)
|
6
|
+
allow(Cloudinary::Uploader).to receive(:destroy)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe ':avatar_files' do
|
10
|
+
let!(:user) { create :user }
|
11
|
+
let!(:avatar_1) { create :file, scope: :avatar, attachable: user }
|
12
|
+
let!(:avatar_2) { create :file, scope: :avatar, attachable: user }
|
13
|
+
|
14
|
+
it 'returns all records even in the singular' do
|
15
|
+
expect(user.avatar_files).to match_array [avatar_1, avatar_2]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ':avatar_files=' do
|
20
|
+
let!(:user) { create :user }
|
21
|
+
let!(:avatar_1) { create :file, scope: :avatar }
|
22
|
+
let!(:avatar_2) { create :file, scope: :avatar }
|
23
|
+
|
24
|
+
context 'when given records' do
|
25
|
+
before { user.avatar_files = [avatar_1, avatar_2] }
|
26
|
+
|
27
|
+
it 'is saved' do
|
28
|
+
expect(user.avatar_files).to match_array [avatar_1, avatar_2]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when given no records' do
|
33
|
+
before { user.avatar_files = [avatar_1, avatar_2] }
|
34
|
+
|
35
|
+
it 'clears the existents' do
|
36
|
+
user.avatar_files = []
|
37
|
+
|
38
|
+
expect(user.avatar_files).to eq []
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe ':avatar' do
|
44
|
+
let!(:user) { create :user }
|
45
|
+
|
46
|
+
context 'with no file' do
|
47
|
+
before do
|
48
|
+
allow(Attachy::File).to receive(:default) { :default }
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'returns a default file' do
|
52
|
+
expect(user.avatar).to eq :default
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with file' do
|
57
|
+
let!(:avatar_1) { create :file, scope: :avatar, attachable: user }
|
58
|
+
let!(:avatar_2) { create :file, scope: :avatar, attachable: user }
|
59
|
+
|
60
|
+
it 'returns just the last one simulating a has_one' do
|
61
|
+
expect(user.avatar).to eq avatar_2
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe ':avatar?' do
|
67
|
+
let!(:user) { create :user }
|
68
|
+
|
69
|
+
context 'with no records' do
|
70
|
+
specify { expect(user.avatar?).to eq false }
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'with records' do
|
74
|
+
before { create :file, scope: :avatar, attachable: user }
|
75
|
+
|
76
|
+
specify { expect(user.avatar?).to eq true }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe ':avatar_metadata' do
|
81
|
+
let!(:user) { create :user }
|
82
|
+
|
83
|
+
it 'returns the metadata' do
|
84
|
+
expect(user.avatar_metadata).to eq(
|
85
|
+
accept: %i[jpg png],
|
86
|
+
multiple: false,
|
87
|
+
scope: :avatar
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
RSpec.describe User, ':photos' do
|
4
|
+
before do
|
5
|
+
allow(Cloudinary::Uploader).to receive(:remove_tag)
|
6
|
+
allow(Cloudinary::Uploader).to receive(:destroy)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe ':photos_files' do
|
10
|
+
let!(:user) { create :user }
|
11
|
+
let!(:photo_1) { create :file, scope: :photos, attachable: user }
|
12
|
+
let!(:photo_2) { create :file, scope: :photos, attachable: user }
|
13
|
+
|
14
|
+
it 'returns all records' do
|
15
|
+
expect(user.photos_files).to match_array [photo_1, photo_2]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ':photos_files=' do
|
20
|
+
let!(:user) { create :user }
|
21
|
+
let!(:photo_1) { create :file, scope: :photo }
|
22
|
+
let!(:photo_2) { create :file, scope: :photo }
|
23
|
+
|
24
|
+
context 'when given records' do
|
25
|
+
before { user.photos_files = [photo_1, photo_2] }
|
26
|
+
|
27
|
+
it 'is saved' do
|
28
|
+
expect(user.photos_files).to match_array [photo_1, photo_2]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when given no records' do
|
33
|
+
before { user.photos_files = [photo_1, photo_2] }
|
34
|
+
|
35
|
+
it 'clears the existents' do
|
36
|
+
user.photos_files = []
|
37
|
+
|
38
|
+
expect(user.photos_files).to eq []
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe ':photo' do
|
44
|
+
let!(:user) { create :user }
|
45
|
+
|
46
|
+
context 'with no file' do
|
47
|
+
it 'returns empty' do
|
48
|
+
expect(user.photos).to eq []
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'with file' do
|
53
|
+
let!(:photo_1) { create :file, scope: :photos, attachable: user }
|
54
|
+
let!(:photo_2) { create :file, scope: :photos, attachable: user }
|
55
|
+
|
56
|
+
it 'returns all records' do
|
57
|
+
expect(user.photos).to match_array [photo_1, photo_2]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe ':photo?' do
|
63
|
+
let!(:user) { create :user }
|
64
|
+
|
65
|
+
context 'with no records' do
|
66
|
+
specify { expect(user.photos?).to eq false }
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with records' do
|
70
|
+
before { create :file, scope: :photos, attachable: user }
|
71
|
+
|
72
|
+
specify { expect(user.photos?).to eq true }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe ':photos_metadata' do
|
77
|
+
let!(:user) { create :user }
|
78
|
+
|
79
|
+
it 'returns the metadata' do
|
80
|
+
expect(user.photos_metadata).to eq(
|
81
|
+
accept: %i[jpg png],
|
82
|
+
maximum: 10,
|
83
|
+
multiple: true,
|
84
|
+
scope: :photos
|
85
|
+
)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|