alchemy_cms 3.0.4 → 3.1.0.beta1
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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -6
- data/Gemfile +4 -7
- data/README.md +207 -115
- data/alchemy_cms.gemspec +10 -9
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +2 -2
- data/app/assets/javascripts/alchemy/alchemy.image_cropper.js.coffee +2 -2
- data/app/assets/javascripts/alchemy/alchemy.js +6 -7
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +1 -43
- data/app/assets/javascripts/alchemy/alchemy.uploader.js.coffee +1 -1
- data/app/assets/stylesheets/alchemy/_mixins.scss +2 -1
- data/app/assets/stylesheets/alchemy/buttons.scss +0 -5
- data/app/assets/stylesheets/alchemy/dialogs.scss +1 -0
- data/app/assets/stylesheets/alchemy/frame.scss +9 -12
- data/app/assets/stylesheets/tinymce/skins/alchemy/content.min.css.scss +11 -2
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +9 -1
- data/app/controllers/alchemy/admin/attachments_controller.rb +2 -4
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +34 -38
- data/app/controllers/alchemy/api/base_controller.rb +19 -0
- data/app/controllers/alchemy/api/contents_controller.rb +35 -0
- data/app/controllers/alchemy/api/elements_controller.rb +29 -0
- data/app/controllers/alchemy/api/pages_controller.rb +32 -0
- data/app/controllers/alchemy/contents_controller.rb +1 -0
- data/app/controllers/alchemy/elements_controller.rb +5 -2
- data/app/controllers/alchemy/pages_controller.rb +4 -1
- data/app/controllers/alchemy/pictures_controller.rb +4 -36
- data/app/helpers/alchemy/admin/essences_helper.rb +5 -2
- data/app/helpers/alchemy/essences_helper.rb +14 -1
- data/app/models/alchemy/content.rb +32 -4
- data/app/models/alchemy/element.rb +2 -16
- data/app/models/alchemy/element/presenters.rb +2 -2
- data/app/models/alchemy/essence_file.rb +5 -0
- data/app/models/alchemy/essence_picture.rb +12 -8
- data/app/models/alchemy/picture.rb +1 -74
- data/app/models/alchemy/picture/transformations.rb +249 -0
- data/app/serializers/alchemy/content_serializer.rb +3 -10
- data/app/serializers/alchemy/element_serializer.rb +6 -3
- data/app/serializers/alchemy/legacy_element_serializer.rb +17 -0
- data/app/views/alchemy/admin/dashboard/_sites.html.erb +14 -4
- data/app/views/alchemy/admin/essence_pictures/crop.html.erb +8 -5
- data/app/views/alchemy/admin/pages/edit.html.erb +9 -9
- data/app/views/alchemy/admin/pictures/info.html.erb +2 -3
- data/app/views/alchemy/admin/tags/edit.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +8 -7
- data/app/views/alchemy/essences/_essence_boolean_view.html.erb +3 -3
- data/app/views/alchemy/essences/_essence_date_editor.html.erb +8 -2
- data/app/views/alchemy/essences/_essence_date_view.html.erb +10 -8
- data/app/views/alchemy/essences/_essence_file_editor.html.erb +48 -53
- data/app/views/alchemy/essences/_essence_file_view.html.erb +5 -5
- data/app/views/alchemy/essences/_essence_html_editor.html.erb +5 -4
- data/app/views/alchemy/essences/_essence_link_editor.html.erb +17 -15
- data/app/views/alchemy/essences/_essence_link_view.html.erb +11 -7
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +4 -2
- data/app/views/alchemy/essences/_essence_picture_view.html.erb +4 -2
- data/app/views/alchemy/essences/_essence_richtext_view.html.erb +5 -4
- data/app/views/alchemy/essences/_essence_select_editor.html.erb +22 -32
- data/app/views/alchemy/essences/_essence_text_view.html.erb +7 -6
- data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +1 -1
- data/app/views/layouts/alchemy/admin.html.erb +5 -3
- data/config/initializers/inflections.rb +3 -0
- data/config/initializers/simple_form.rb +1 -1
- data/config/locales/alchemy.en.yml +0 -1
- data/config/routes.rb +14 -0
- data/lib/alchemy/capistrano.rb +71 -0
- data/lib/alchemy/engine.rb +0 -3
- data/lib/alchemy/essence.rb +1 -1
- data/lib/alchemy/permissions.rb +19 -5
- data/lib/alchemy/picture_attributes.rb +1 -1
- data/lib/alchemy/test_support/auth_helpers.rb +1 -1
- data/lib/alchemy/test_support/essence_shared_examples.rb +37 -22
- data/lib/alchemy/test_support/integration_helpers.rb +1 -1
- data/lib/alchemy/tinymce.rb +21 -4
- data/lib/alchemy/upgrader/three_point_one.rb +43 -0
- data/lib/alchemy/upgrader/three_point_zero.rb +13 -0
- data/lib/alchemy/version.rb +2 -1
- data/lib/rails/generators/alchemy/module/module_generator.rb +30 -0
- data/lib/rails/generators/alchemy/module/templates/ability.rb.tt +11 -0
- data/lib/rails/generators/alchemy/module/templates/controller.rb.tt +2 -0
- data/lib/rails/generators/alchemy/module/templates/module_config.rb.tt +15 -0
- data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +0 -1
- data/lib/rails/templates/alchemy.rb +2 -2
- data/lib/tasks/alchemy/db.rake +7 -1
- data/spec/controllers/admin/attachments_controller_spec.rb +38 -38
- data/spec/controllers/admin/base_controller_spec.rb +18 -18
- data/spec/controllers/admin/clipboard_controller_spec.rb +23 -18
- data/spec/controllers/admin/contents_controller_spec.rb +33 -27
- data/spec/controllers/admin/dashboard_controller_spec.rb +14 -14
- data/spec/controllers/admin/elements_controller_spec.rb +125 -105
- data/spec/controllers/admin/essence_files_controller_spec.rb +6 -7
- data/spec/controllers/admin/essence_pictures_controller_spec.rb +52 -42
- data/spec/controllers/admin/languages_controller_spec.rb +3 -3
- data/spec/controllers/admin/pages_controller_spec.rb +81 -71
- data/spec/controllers/admin/pictures_controller_spec.rb +69 -72
- data/spec/controllers/admin/resources_controller_spec.rb +5 -5
- data/spec/controllers/admin/trash_controller_spec.rb +15 -12
- data/spec/controllers/alchemy/admin/tags_controller_spec.rb +8 -8
- data/spec/controllers/alchemy/api/contents_controller_spec.rb +73 -0
- data/spec/controllers/alchemy/api/elements_controller_spec.rb +69 -0
- data/spec/controllers/alchemy/api/pages_controller_spec.rb +86 -0
- data/spec/controllers/attachments_controller_spec.rb +8 -8
- data/spec/controllers/contents_controller_spec.rb +22 -0
- data/spec/controllers/elements_controller_spec.rb +10 -4
- data/spec/controllers/messages_controller_spec.rb +35 -34
- data/spec/controllers/pages_controller_spec.rb +37 -28
- data/spec/controllers/pictures_controller_spec.rb +90 -23
- data/spec/dummy/app/models/dummy_user.rb +0 -4
- data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_editor.html.erb +11 -0
- data/spec/dummy/config/alchemy/elements.yml +22 -1
- data/spec/dummy/config/alchemy/page_layouts.yml +4 -0
- data/spec/dummy/config/application.rb +2 -1
- data/spec/dummy/config/environments/test.rb +3 -1
- data/spec/features/admin/dashboard_spec.rb +41 -6
- data/spec/features/admin/language_tree_feature_spec.rb +3 -3
- data/spec/features/admin/legacy_page_url_management_spec.rb +1 -1
- data/spec/features/admin/link_overlay_spec.rb +7 -7
- data/spec/features/admin/locale_select_feature_spec.rb +5 -2
- data/spec/features/admin/modules_integration_spec.rb +1 -1
- data/spec/features/admin/page_creation_feature_spec.rb +3 -2
- data/spec/features/admin/page_editing_feature_spec.rb +66 -79
- data/spec/features/admin/picture_library_integration_spec.rb +8 -8
- data/spec/features/admin/resources_integration_spec.rb +21 -21
- data/spec/features/admin/tinymce_feature_spec.rb +36 -0
- data/spec/features/navigation_spec.rb +1 -1
- data/spec/features/page_feature_spec.rb +34 -34
- data/spec/features/picture_security_spec.rb +4 -4
- data/spec/features/security_spec.rb +1 -1
- data/spec/features/translation_integration_spec.rb +7 -7
- data/spec/helpers/admin/base_helper_spec.rb +51 -49
- data/spec/helpers/admin/contents_helper_spec.rb +11 -11
- data/spec/helpers/admin/elements_helper_spec.rb +20 -17
- data/spec/helpers/admin/essences_helper_spec.rb +42 -11
- data/spec/helpers/admin/navigation_helper_spec.rb +64 -54
- data/spec/helpers/admin/pages_helper_spec.rb +10 -10
- data/spec/helpers/admin/tags_helper_spec.rb +16 -16
- data/spec/helpers/base_helper_spec.rb +11 -11
- data/spec/helpers/elements_block_helper_spec.rb +24 -24
- data/spec/helpers/elements_helper_spec.rb +46 -46
- data/spec/helpers/essences_helper_spec.rb +90 -17
- data/spec/helpers/pages_helper_spec.rb +53 -53
- data/spec/helpers/picture_url_helpers_spec.rb +6 -6
- data/spec/helpers/url_helper_spec.rb +32 -32
- data/spec/libraries/config_spec.rb +9 -9
- data/spec/libraries/controller_actions_spec.rb +14 -14
- data/spec/libraries/i18n_spec.rb +6 -6
- data/spec/libraries/kaminari/scoped_pagination_url_helper_spec.rb +4 -4
- data/spec/libraries/modules_spec.rb +4 -4
- data/spec/libraries/mount_point_spec.rb +13 -13
- data/spec/libraries/page_layout_spec.rb +24 -24
- data/spec/libraries/permissions_spec.rb +97 -80
- data/spec/libraries/resource_spec.rb +37 -37
- data/spec/libraries/resources_helper_spec.rb +19 -19
- data/spec/libraries/shell_spec.rb +17 -17
- data/spec/libraries/template_tracker_spec.rb +14 -14
- data/spec/libraries/tinymce_spec.rb +8 -8
- data/spec/libraries/userstamp_spec.rb +2 -2
- data/spec/mailers/messages_spec.rb +4 -4
- data/spec/models/attachment_spec.rb +86 -30
- data/spec/models/cell_spec.rb +10 -10
- data/spec/models/content_spec.rb +106 -46
- data/spec/models/element_spec.rb +94 -115
- data/spec/models/essence_date_spec.rb +1 -1
- data/spec/models/essence_file_spec.rb +4 -4
- data/spec/models/essence_picture_spec.rb +56 -25
- data/spec/models/essence_richtext_spec.rb +1 -1
- data/spec/models/essence_text_spec.rb +7 -7
- data/spec/models/language_spec.rb +12 -12
- data/spec/models/legacy_page_url_spec.rb +2 -2
- data/spec/models/message_spec.rb +12 -5
- data/spec/models/page_spec.rb +259 -235
- data/spec/models/picture_spec.rb +72 -166
- data/spec/models/site_spec.rb +41 -41
- data/spec/models/tag_spec.rb +7 -7
- data/spec/routing/api_routing_spec.rb +150 -0
- data/spec/routing/routing_spec.rb +28 -28
- data/spec/spec_helper.rb +6 -5
- data/spec/support/hint_examples.rb +5 -5
- data/spec/support/transformation_examples.rb +173 -0
- data/spec/tasks/helpers_spec.rb +29 -29
- data/spec/views/essences/essence_boolean_editor_spec.rb +32 -0
- data/spec/views/essences/essence_boolean_view_spec.rb +2 -2
- data/spec/views/essences/essence_date_view_spec.rb +1 -1
- data/spec/views/essences/essence_link_view_spec.rb +11 -0
- data/spec/views/essences/essence_picture_view_spec.rb +56 -11
- data/spec/views/essences/essence_richtext_view_spec.rb +12 -0
- data/spec/views/essences/essence_text_view_spec.rb +12 -0
- data/vendor/assets/javascripts/tinymce/langs/de.js +20 -2
- data/vendor/assets/javascripts/tinymce/langs/fr.js +14 -1
- data/vendor/assets/javascripts/tinymce/langs/nl.js +22 -4
- data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/code/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/hr/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/link/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/tabfocus/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/table/plugin.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/themes/modern/theme.min.js +1 -1
- data/vendor/assets/javascripts/tinymce/tinymce.min.js +11 -10
- metadata +72 -42
- data/app/views/alchemy/messages/contact_form_mail.es.text.erb +0 -12
- data/config/locales/alchemy.es.yml +0 -958
- data/config/locales/alchemy.ru.yml +0 -837
- data/config/locales/simple_form.es.yml +0 -6
- data/config/locales/simple_form.ru.yml +0 -25
- data/lib/rails/generators/alchemy/scaffold/files/alchemy.es.yml +0 -31
- data/vendor/assets/javascripts/tinymce/langs/es.js +0 -197
- data/vendor/assets/javascripts/tinymce/langs/ru.js +0 -197
data/spec/models/picture_spec.rb
CHANGED
|
@@ -4,6 +4,10 @@ require 'spec_helper'
|
|
|
4
4
|
module Alchemy
|
|
5
5
|
describe Picture do
|
|
6
6
|
|
|
7
|
+
it_behaves_like "has image transformations" do
|
|
8
|
+
let(:picture) { FactoryGirl.build_stubbed(:picture) }
|
|
9
|
+
end
|
|
10
|
+
|
|
7
11
|
let :image_file do
|
|
8
12
|
File.new(File.expand_path('../../fixtures/image.png', __FILE__))
|
|
9
13
|
end
|
|
@@ -12,24 +16,24 @@ module Alchemy
|
|
|
12
16
|
|
|
13
17
|
it "is valid with valid attributes" do
|
|
14
18
|
picture = Picture.new(image_file: image_file)
|
|
15
|
-
picture.
|
|
19
|
+
expect(picture).to be_valid
|
|
16
20
|
end
|
|
17
21
|
|
|
18
22
|
it "is not valid without image file" do
|
|
19
23
|
picture = Picture.new
|
|
20
|
-
picture.
|
|
24
|
+
expect(picture).not_to be_valid
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
it "is valid with capitalized image file extension" do
|
|
24
28
|
image_file = File.new(File.expand_path('../../fixtures/image2.PNG', __FILE__))
|
|
25
29
|
picture = Picture.new(image_file: image_file)
|
|
26
|
-
picture.
|
|
30
|
+
expect(picture).to be_valid
|
|
27
31
|
end
|
|
28
32
|
|
|
29
33
|
it "is valid with jpeg image file extension" do
|
|
30
34
|
image_file = File.new(File.expand_path('../../fixtures/image3.jpeg', __FILE__))
|
|
31
35
|
picture = Picture.new(image_file: image_file)
|
|
32
|
-
picture.
|
|
36
|
+
expect(picture).to be_valid
|
|
33
37
|
end
|
|
34
38
|
|
|
35
39
|
context 'with enabled preprocess_image_resize config option' do
|
|
@@ -38,7 +42,7 @@ module Alchemy
|
|
|
38
42
|
end
|
|
39
43
|
|
|
40
44
|
before do
|
|
41
|
-
Config.
|
|
45
|
+
allow(Config).to receive(:get) do |arg|
|
|
42
46
|
if arg == :preprocess_image_resize
|
|
43
47
|
'10x10'
|
|
44
48
|
end
|
|
@@ -54,15 +58,15 @@ module Alchemy
|
|
|
54
58
|
describe '#suffix' do
|
|
55
59
|
it "should return the suffix of original filename" do
|
|
56
60
|
pic = stub_model(Picture, image_file_name: 'kitten.JPG')
|
|
57
|
-
pic.
|
|
58
|
-
pic.suffix.
|
|
61
|
+
allow(pic).to receive(:image_file).and_return(OpenStruct.new({ext: 'jpg'}))
|
|
62
|
+
expect(pic.suffix).to eq("jpg")
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
context "image has no suffix" do
|
|
62
66
|
it "should return empty string" do
|
|
63
67
|
pic = stub_model(Picture, image_file_name: 'kitten')
|
|
64
|
-
pic.
|
|
65
|
-
pic.suffix.
|
|
68
|
+
allow(pic).to receive(:image_file).and_return(OpenStruct.new({ext: ''}))
|
|
69
|
+
expect(pic.suffix).to eq("")
|
|
66
70
|
end
|
|
67
71
|
end
|
|
68
72
|
end
|
|
@@ -70,22 +74,22 @@ module Alchemy
|
|
|
70
74
|
describe '#humanized_name' do
|
|
71
75
|
it "should return a humanized version of original filename" do
|
|
72
76
|
pic = stub_model(Picture, image_file_name: 'cute_kitten.JPG')
|
|
73
|
-
pic.
|
|
74
|
-
pic.humanized_name.
|
|
77
|
+
allow(pic).to receive(:image_file).and_return(OpenStruct.new({ext: 'jpg'}))
|
|
78
|
+
expect(pic.humanized_name).to eq("cute kitten")
|
|
75
79
|
end
|
|
76
80
|
|
|
77
81
|
it "should not remove incidents of suffix from filename" do
|
|
78
82
|
pic = stub_model(Picture, image_file_name: 'cute_kitten_mo.jpgi.JPG')
|
|
79
|
-
pic.
|
|
80
|
-
pic.humanized_name.
|
|
81
|
-
pic.humanized_name.
|
|
83
|
+
allow(pic).to receive(:image_file).and_return(OpenStruct.new({ext: 'jpg'}))
|
|
84
|
+
expect(pic.humanized_name).to eq("cute kitten mo.jpgi")
|
|
85
|
+
expect(pic.humanized_name).not_to eq("cute kitten moi")
|
|
82
86
|
end
|
|
83
87
|
|
|
84
88
|
context "image has no suffix" do
|
|
85
89
|
it "should return humanized name" do
|
|
86
90
|
pic = stub_model(Picture, image_file_name: 'cute_kitten')
|
|
87
|
-
pic.
|
|
88
|
-
pic.humanized_name.
|
|
91
|
+
allow(pic).to receive(:suffix).and_return("")
|
|
92
|
+
expect(pic.humanized_name).to eq("cute kitten")
|
|
89
93
|
end
|
|
90
94
|
end
|
|
91
95
|
end
|
|
@@ -94,7 +98,7 @@ module Alchemy
|
|
|
94
98
|
before { @pic = stub_model(Picture, id: 1) }
|
|
95
99
|
|
|
96
100
|
it "should return a sha1 hash" do
|
|
97
|
-
@pic.security_token.
|
|
101
|
+
expect(@pic.security_token).to match(/\b([a-f0-9]{16})\b/)
|
|
98
102
|
end
|
|
99
103
|
|
|
100
104
|
it "should return a 16 chars long hash" do
|
|
@@ -103,22 +107,22 @@ module Alchemy
|
|
|
103
107
|
|
|
104
108
|
it "should convert crop true value into string" do
|
|
105
109
|
digest = PictureAttributes.secure({id: @pic.id, crop: 'crop'})
|
|
106
|
-
@pic.security_token(crop: true).
|
|
110
|
+
expect(@pic.security_token(crop: true)).to eq(digest)
|
|
107
111
|
end
|
|
108
112
|
|
|
109
113
|
it "should always include picture id" do
|
|
110
114
|
digest = PictureAttributes.secure({id: @pic.id})
|
|
111
|
-
@pic.security_token.
|
|
115
|
+
expect(@pic.security_token).to eq(digest)
|
|
112
116
|
end
|
|
113
117
|
|
|
114
118
|
it "should remove all not suitable options" do
|
|
115
119
|
digest = PictureAttributes.secure({id: @pic.id})
|
|
116
|
-
@pic.security_token({foo: 'baz'}).
|
|
120
|
+
expect(@pic.security_token({foo: 'baz'})).to eq(digest)
|
|
117
121
|
end
|
|
118
122
|
|
|
119
123
|
it "should remove all option values that have nil values" do
|
|
120
124
|
digest = PictureAttributes.secure({id: @pic.id})
|
|
121
|
-
@pic.security_token({crop: nil}).
|
|
125
|
+
expect(@pic.security_token({crop: nil})).to eq(digest)
|
|
122
126
|
end
|
|
123
127
|
end
|
|
124
128
|
|
|
@@ -127,29 +131,29 @@ module Alchemy
|
|
|
127
131
|
|
|
128
132
|
context "with 'recent' as argument" do
|
|
129
133
|
it 'should call the .recent scope' do
|
|
130
|
-
Picture.
|
|
131
|
-
Picture.filtered_by('recent').
|
|
134
|
+
expect(Picture).to receive(:recent).and_return(picture)
|
|
135
|
+
expect(Picture.filtered_by('recent')).to eq(picture)
|
|
132
136
|
end
|
|
133
137
|
end
|
|
134
138
|
|
|
135
139
|
context "with 'last_upload' as argument" do
|
|
136
140
|
it 'should call the .last_upload scope' do
|
|
137
|
-
Picture.
|
|
138
|
-
Picture.filtered_by('last_upload').
|
|
141
|
+
expect(Picture).to receive(:last_upload).and_return(picture)
|
|
142
|
+
expect(Picture.filtered_by('last_upload')).to eq(picture)
|
|
139
143
|
end
|
|
140
144
|
end
|
|
141
145
|
|
|
142
146
|
context "with 'without_tag' as argument" do
|
|
143
147
|
it 'should call the .without_tag scope' do
|
|
144
|
-
Picture.
|
|
145
|
-
Picture.filtered_by('without_tag').
|
|
148
|
+
expect(Picture).to receive(:without_tag).and_return(picture)
|
|
149
|
+
expect(Picture.filtered_by('without_tag')).to eq(picture)
|
|
146
150
|
end
|
|
147
151
|
end
|
|
148
152
|
|
|
149
153
|
context "with no argument" do
|
|
150
154
|
it 'should return the scoped collection' do
|
|
151
|
-
Picture.
|
|
152
|
-
Picture.filtered_by('').
|
|
155
|
+
expect(Picture).to receive(:all).and_return(picture)
|
|
156
|
+
expect(Picture.filtered_by('')).to eq(picture)
|
|
153
157
|
end
|
|
154
158
|
end
|
|
155
159
|
end
|
|
@@ -160,9 +164,9 @@ module Alchemy
|
|
|
160
164
|
same_upload = Picture.create!(image_file: image_file, upload_hash: '123')
|
|
161
165
|
most_recent = Picture.create!(image_file: image_file, upload_hash: '123')
|
|
162
166
|
|
|
163
|
-
Picture.last_upload.
|
|
164
|
-
Picture.last_upload.
|
|
165
|
-
Picture.last_upload.
|
|
167
|
+
expect(Picture.last_upload).to include(most_recent)
|
|
168
|
+
expect(Picture.last_upload).to include(same_upload)
|
|
169
|
+
expect(Picture.last_upload).not_to include(other_upload)
|
|
166
170
|
|
|
167
171
|
[other_upload, same_upload, most_recent].each { |p| p.destroy }
|
|
168
172
|
end
|
|
@@ -178,11 +182,11 @@ module Alchemy
|
|
|
178
182
|
end
|
|
179
183
|
|
|
180
184
|
it "should return all pictures that have been created in the last 24 hours" do
|
|
181
|
-
Picture.recent.
|
|
185
|
+
expect(Picture.recent).to include(@recent)
|
|
182
186
|
end
|
|
183
187
|
|
|
184
188
|
it "should not return old pictures" do
|
|
185
|
-
Picture.recent.
|
|
189
|
+
expect(Picture.recent).not_to include(@old_picture)
|
|
186
190
|
end
|
|
187
191
|
end
|
|
188
192
|
|
|
@@ -201,56 +205,6 @@ module Alchemy
|
|
|
201
205
|
end
|
|
202
206
|
end
|
|
203
207
|
|
|
204
|
-
describe '#default_mask' do
|
|
205
|
-
before do
|
|
206
|
-
picture.stub(:image_file_width).and_return(200)
|
|
207
|
-
picture.stub(:image_file_height).and_return(100)
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
it "should return a Hash" do
|
|
211
|
-
expect(picture.default_mask('10x10')).to be_a(Hash)
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
context "cropping the picture to 200x50 pixel" do
|
|
215
|
-
it "should contain the correct coordination values in the hash" do
|
|
216
|
-
expect(picture.default_mask('200x50')).to eq({x1: 0, y1: 25, x2: 200, y2: 75})
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
context "if picture´s cropping size is 0x0 pixel" do
|
|
221
|
-
it "should not crop the picture" do
|
|
222
|
-
expect(picture.default_mask('0x0')).to eq({x1: 0, y1: 0, x2: 200, y2: 100})
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
context "cropping the picture to 50x100 pixel" do
|
|
227
|
-
it "should contain the correct coordination values in the hash" do
|
|
228
|
-
expect(picture.default_mask('50x100')).to eq({x1: 75, y1: 0, x2: 125, y2: 100})
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
describe "#cropped_thumbnail_size" do
|
|
234
|
-
context "if given size is blank or 111x93" do
|
|
235
|
-
it "should return the default size of '111x93'" do
|
|
236
|
-
expect(picture.cropped_thumbnail_size('')).to eq('111x93')
|
|
237
|
-
expect(picture.cropped_thumbnail_size('111x93')).to eq('111x93')
|
|
238
|
-
end
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
context "if the given width is 400 and the height is 300 because of picture cropping" do
|
|
242
|
-
it "should return the correct recalculated size value" do
|
|
243
|
-
expect(picture.cropped_thumbnail_size('400x300')).to eq('111x83')
|
|
244
|
-
end
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
context "if the given width is 300 and the height is 400 because of picture cropping" do
|
|
248
|
-
it "should return the correct recalculated size value" do
|
|
249
|
-
expect(picture.cropped_thumbnail_size('300x400')).to eq('70x93')
|
|
250
|
-
end
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
|
|
254
208
|
describe "#image_file_dimensions" do
|
|
255
209
|
it "should return the width and height in the format of '1024x768'" do
|
|
256
210
|
picture.image_file = image_file
|
|
@@ -261,23 +215,23 @@ module Alchemy
|
|
|
261
215
|
describe '#update_name_and_tag_list!' do
|
|
262
216
|
let(:picture) { Picture.new(image_file: image_file) }
|
|
263
217
|
|
|
264
|
-
before { picture.
|
|
218
|
+
before { allow(picture).to receive(:save!).and_return(true) }
|
|
265
219
|
|
|
266
220
|
it "updates tag_list" do
|
|
267
|
-
picture.
|
|
221
|
+
expect(picture).to receive(:tag_list=).with('Foo')
|
|
268
222
|
picture.update_name_and_tag_list!({pictures_tag_list: 'Foo'})
|
|
269
223
|
end
|
|
270
224
|
|
|
271
225
|
context 'name is present' do
|
|
272
226
|
it "updates name" do
|
|
273
|
-
picture.
|
|
227
|
+
expect(picture).to receive(:name=).with('Foo')
|
|
274
228
|
picture.update_name_and_tag_list!({pictures_name: 'Foo'})
|
|
275
229
|
end
|
|
276
230
|
end
|
|
277
231
|
|
|
278
232
|
context 'name is not present' do
|
|
279
233
|
it "does not update name" do
|
|
280
|
-
picture.
|
|
234
|
+
expect(picture).not_to receive(:name=).with('Foo')
|
|
281
235
|
picture.update_name_and_tag_list!({pictures_name: ''})
|
|
282
236
|
end
|
|
283
237
|
end
|
|
@@ -289,14 +243,14 @@ module Alchemy
|
|
|
289
243
|
let(:picture) { build_stubbed(:picture, name: 'Cute kittens.jpg') }
|
|
290
244
|
|
|
291
245
|
it "returns a uri escaped name" do
|
|
292
|
-
|
|
246
|
+
is_expected.to eq('Cute+kittens')
|
|
293
247
|
end
|
|
294
248
|
|
|
295
249
|
context 'with blank name' do
|
|
296
250
|
let(:picture) { build_stubbed(:picture, name: '') }
|
|
297
251
|
|
|
298
252
|
it "returns generic name" do
|
|
299
|
-
|
|
253
|
+
is_expected.to eq("image_#{picture.id}")
|
|
300
254
|
end
|
|
301
255
|
end
|
|
302
256
|
end
|
|
@@ -307,107 +261,60 @@ module Alchemy
|
|
|
307
261
|
let(:picture) { build_stubbed(:picture, image_file_name: 'cute-kittens.jpg', image_file_size: 1024) }
|
|
308
262
|
|
|
309
263
|
it "returns a hash containing data for jquery fileuploader" do
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
264
|
+
is_expected.to be_an_instance_of(Hash)
|
|
265
|
+
is_expected.to include(name: picture.image_file_name)
|
|
266
|
+
is_expected.to include(size: picture.image_file_size)
|
|
313
267
|
end
|
|
314
268
|
|
|
315
269
|
context 'with error' do
|
|
316
270
|
let(:picture) { build_stubbed(:picture) }
|
|
317
271
|
|
|
318
272
|
before do
|
|
319
|
-
picture.
|
|
273
|
+
expect(picture).to receive(:errors).and_return({image_file: %w(stupid_cats)})
|
|
320
274
|
end
|
|
321
275
|
|
|
322
276
|
it "returns hash with error message" do
|
|
323
|
-
|
|
324
|
-
|
|
277
|
+
is_expected.to be_an_instance_of(Hash)
|
|
278
|
+
is_expected.to include(error: 'stupid_cats')
|
|
325
279
|
end
|
|
326
280
|
end
|
|
327
281
|
end
|
|
328
282
|
|
|
329
|
-
describe '#landscape_format?' do
|
|
330
|
-
subject { picture.landscape_format? }
|
|
331
|
-
|
|
332
|
-
let(:picture) { build_stubbed(:picture) }
|
|
333
|
-
|
|
334
|
-
context 'image has landscape format' do
|
|
335
|
-
before { picture.stub_chain(:image_file, :landscape?).and_return(true) }
|
|
336
|
-
it { should be_true }
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
context 'image has portrait format' do
|
|
340
|
-
before { picture.stub_chain(:image_file, :landscape?).and_return(false) }
|
|
341
|
-
it { should be_false }
|
|
342
|
-
end
|
|
343
|
-
|
|
344
|
-
it "is aliased as landscape?" do
|
|
345
|
-
picture.respond_to?(:landscape?).should be_true
|
|
346
|
-
end
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
describe '#portrait_format?' do
|
|
350
|
-
subject { picture.portrait_format? }
|
|
351
|
-
|
|
352
|
-
let(:picture) { build_stubbed(:picture) }
|
|
353
|
-
|
|
354
|
-
context 'image has portrait format' do
|
|
355
|
-
before { picture.stub_chain(:image_file, :portrait?).and_return(true) }
|
|
356
|
-
it { should be_true }
|
|
357
|
-
end
|
|
358
|
-
|
|
359
|
-
context 'image has landscape format' do
|
|
360
|
-
before { picture.stub_chain(:image_file, :portrait?).and_return(false) }
|
|
361
|
-
it { should be_false }
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
it "is aliased as portrait?" do
|
|
365
|
-
picture.respond_to?(:portrait?).should be_true
|
|
366
|
-
end
|
|
367
|
-
end
|
|
368
|
-
|
|
369
|
-
describe '#square_format?' do
|
|
370
|
-
subject { picture.square_format? }
|
|
371
|
-
|
|
372
|
-
let(:picture) { build_stubbed(:picture) }
|
|
373
|
-
|
|
374
|
-
context 'image has square format' do
|
|
375
|
-
before { picture.stub_chain(:image_file, :aspect_ratio).and_return(1.0) }
|
|
376
|
-
it { should be_true }
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
context 'image has rectangle format' do
|
|
380
|
-
before { picture.stub_chain(:image_file, :aspect_ratio).and_return(1.8) }
|
|
381
|
-
it { should be_false }
|
|
382
|
-
end
|
|
383
|
-
|
|
384
|
-
it "is aliased as square?" do
|
|
385
|
-
picture.respond_to?(:square?).should be_true
|
|
386
|
-
end
|
|
387
|
-
end
|
|
388
|
-
|
|
389
283
|
describe '#restricted?' do
|
|
390
284
|
subject { picture.restricted? }
|
|
391
285
|
|
|
392
286
|
let(:picture) { build_stubbed(:picture) }
|
|
393
287
|
|
|
394
288
|
context 'is assigned on pages' do
|
|
395
|
-
before { picture.stub_chain(:pages, :any?).and_return(true) }
|
|
396
|
-
|
|
397
289
|
context 'that are all restricted' do
|
|
398
|
-
before
|
|
399
|
-
|
|
290
|
+
before do
|
|
291
|
+
expect(picture).to receive(:pages).at_least(:once).and_return double(
|
|
292
|
+
not_restricted: double(blank?: true),
|
|
293
|
+
any?: true
|
|
294
|
+
)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it { is_expected.to be_truthy }
|
|
400
298
|
end
|
|
401
299
|
|
|
402
300
|
context 'that are not all restricted' do
|
|
403
|
-
before
|
|
404
|
-
|
|
301
|
+
before do
|
|
302
|
+
expect(picture).to receive(:pages).at_least(:once).and_return double(
|
|
303
|
+
not_restricted: double(blank?: false),
|
|
304
|
+
any?: true
|
|
305
|
+
)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it { is_expected.to be_falsey }
|
|
405
309
|
end
|
|
406
310
|
end
|
|
407
311
|
|
|
408
312
|
context 'is not assigned on any page' do
|
|
409
|
-
before
|
|
410
|
-
|
|
313
|
+
before do
|
|
314
|
+
expect(picture).to receive(:pages).and_return double(any?: false)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it { is_expected.to be_falsey }
|
|
411
318
|
end
|
|
412
319
|
end
|
|
413
320
|
|
|
@@ -415,10 +322,9 @@ module Alchemy
|
|
|
415
322
|
subject { Picture.find_paginated({query: 'kitten'}, 5) }
|
|
416
323
|
|
|
417
324
|
it "finds pages by name" do
|
|
418
|
-
Picture.
|
|
325
|
+
expect(Picture).to receive(:named).with('kitten').and_return(Picture.none)
|
|
419
326
|
subject
|
|
420
327
|
end
|
|
421
328
|
end
|
|
422
|
-
|
|
423
329
|
end
|
|
424
330
|
end
|
data/spec/models/site_spec.rb
CHANGED
|
@@ -9,15 +9,15 @@ module Alchemy
|
|
|
9
9
|
subject { FactoryGirl.build(:site) }
|
|
10
10
|
|
|
11
11
|
it 'should start out with no languages' do
|
|
12
|
-
subject.languages.
|
|
12
|
+
expect(subject.languages).to be_empty
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
context 'when being saved' do
|
|
16
16
|
context 'when it has no languages yet' do
|
|
17
17
|
it 'should automatically create a default language' do
|
|
18
18
|
subject.save!
|
|
19
|
-
subject.languages.length.
|
|
20
|
-
subject.languages.first.
|
|
19
|
+
expect(subject.languages.length).to eq(1) # using count returns 0, although the resulting array has a length of 1 / O.o
|
|
20
|
+
expect(subject.languages.first).to be_default
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
@@ -26,7 +26,7 @@ module Alchemy
|
|
|
26
26
|
before { subject.languages << language }
|
|
27
27
|
|
|
28
28
|
it 'should not create any additional languages' do
|
|
29
|
-
subject.languages.
|
|
29
|
+
expect(subject.languages).to eq([language])
|
|
30
30
|
|
|
31
31
|
expect { subject.save! }.
|
|
32
32
|
to_not change(subject, "languages")
|
|
@@ -46,32 +46,32 @@ module Alchemy
|
|
|
46
46
|
|
|
47
47
|
context "when the request doesn't match anything" do
|
|
48
48
|
let(:host) { 'oogabooga.com' }
|
|
49
|
-
it {
|
|
49
|
+
it { is_expected.to eq(default_site) }
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
context "when the request matches a site's host field" do
|
|
53
53
|
let(:host) { 'www.magiclabs.de' }
|
|
54
|
-
it {
|
|
54
|
+
it { is_expected.to eq(magiclabs_site) }
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
context "when the request matches one of the site's aliases" do
|
|
58
58
|
let(:host) { 'magiclabs.com' }
|
|
59
|
-
it {
|
|
59
|
+
it { is_expected.to eq(magiclabs_site) }
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
context "when the request matches the site's first alias" do
|
|
63
63
|
let(:host) { 'magiclabs.de' }
|
|
64
|
-
it {
|
|
64
|
+
it { is_expected.to eq(magiclabs_site) }
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
context "when the request matches the site's last alias" do
|
|
68
68
|
let(:host) { 'www.magiclabs.com' }
|
|
69
|
-
it {
|
|
69
|
+
it { is_expected.to eq(magiclabs_site) }
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
context "when the request host matches only part of a site's aliases" do
|
|
73
73
|
let(:host) { 'labs.com' }
|
|
74
|
-
it {
|
|
74
|
+
it { is_expected.to eq(default_site) }
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
|
|
@@ -79,19 +79,19 @@ module Alchemy
|
|
|
79
79
|
context 'when set to a site' do
|
|
80
80
|
before { Site.current = site }
|
|
81
81
|
specify "Language should be scoped to that site" do
|
|
82
|
-
Language.all.to_sql.
|
|
82
|
+
expect(Language.all.to_sql).to match(/alchemy_languages.+site_id.+#{site.id}/)
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
context 'when set to nil' do
|
|
87
87
|
before { Site.current = nil }
|
|
88
88
|
specify "Language should not be scoped to a site" do
|
|
89
|
-
Language.all.to_sql.
|
|
89
|
+
expect(Language.all.to_sql).not_to match(/alchemy_languages.+site_id.+#{site.id}/)
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
it "should return default site" do
|
|
93
|
-
Site.current.
|
|
94
|
-
Site.current.
|
|
93
|
+
expect(Site.current).not_to be_nil
|
|
94
|
+
expect(Site.current).to eq(Site.default)
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
end
|
|
@@ -104,17 +104,17 @@ module Alchemy
|
|
|
104
104
|
|
|
105
105
|
context "with file present" do
|
|
106
106
|
let(:definitions) { [{'name' => 'lala'}] }
|
|
107
|
-
before { YAML.
|
|
108
|
-
it {
|
|
107
|
+
before { expect(YAML).to receive(:load_file).and_return(definitions) }
|
|
108
|
+
it { is_expected.to eq(definitions) }
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
context "with empty file" do
|
|
112
|
-
before { YAML.
|
|
113
|
-
it {
|
|
112
|
+
before { expect(YAML).to receive(:load_file).and_return(false) }
|
|
113
|
+
it { is_expected.to eq([]) }
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
context "with no file present" do
|
|
117
|
-
it {
|
|
117
|
+
it { is_expected.to eq([]) }
|
|
118
118
|
end
|
|
119
119
|
end
|
|
120
120
|
|
|
@@ -126,17 +126,17 @@ module Alchemy
|
|
|
126
126
|
|
|
127
127
|
context "with file present" do
|
|
128
128
|
let(:definitions) { [{'name' => 'lala'}] }
|
|
129
|
-
before { YAML.
|
|
130
|
-
it {
|
|
129
|
+
before { expect(YAML).to receive(:load_file).and_return(definitions) }
|
|
130
|
+
it { is_expected.to eq(definitions) }
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
context "with empty file" do
|
|
134
|
-
before { YAML.
|
|
135
|
-
it {
|
|
134
|
+
before { expect(YAML).to receive(:load_file).and_return(false) }
|
|
135
|
+
it { is_expected.to eq([]) }
|
|
136
136
|
end
|
|
137
137
|
|
|
138
138
|
context "with no file present" do
|
|
139
|
-
it {
|
|
139
|
+
it { is_expected.to eq([]) }
|
|
140
140
|
end
|
|
141
141
|
end
|
|
142
142
|
|
|
@@ -148,17 +148,17 @@ module Alchemy
|
|
|
148
148
|
|
|
149
149
|
context "with file present" do
|
|
150
150
|
let(:definitions) { [{'name' => 'lala'}] }
|
|
151
|
-
before { YAML.
|
|
152
|
-
it {
|
|
151
|
+
before { expect(YAML).to receive(:load_file).and_return(definitions) }
|
|
152
|
+
it { is_expected.to eq(definitions) }
|
|
153
153
|
end
|
|
154
154
|
|
|
155
155
|
context "with empty file" do
|
|
156
|
-
before { YAML.
|
|
157
|
-
it {
|
|
156
|
+
before { expect(YAML).to receive(:load_file).and_return(false) }
|
|
157
|
+
it { is_expected.to eq([]) }
|
|
158
158
|
end
|
|
159
159
|
|
|
160
160
|
context "with no file present" do
|
|
161
|
-
it {
|
|
161
|
+
it { is_expected.to eq([]) }
|
|
162
162
|
end
|
|
163
163
|
end
|
|
164
164
|
|
|
@@ -170,17 +170,17 @@ module Alchemy
|
|
|
170
170
|
|
|
171
171
|
context "with file present" do
|
|
172
172
|
let(:definitions) { [{'name' => 'lala'}] }
|
|
173
|
-
before { YAML.
|
|
174
|
-
it {
|
|
173
|
+
before { expect(YAML).to receive(:load_file).and_return(definitions) }
|
|
174
|
+
it { is_expected.to eq(definitions) }
|
|
175
175
|
end
|
|
176
176
|
|
|
177
177
|
context "with empty file" do
|
|
178
|
-
before { YAML.
|
|
179
|
-
it {
|
|
178
|
+
before { expect(YAML).to receive(:load_file).and_return(false) }
|
|
179
|
+
it { is_expected.to eq([]) }
|
|
180
180
|
end
|
|
181
181
|
|
|
182
182
|
context "with no file present" do
|
|
183
|
-
it {
|
|
183
|
+
it { is_expected.to eq([]) }
|
|
184
184
|
end
|
|
185
185
|
end
|
|
186
186
|
|
|
@@ -189,17 +189,17 @@ module Alchemy
|
|
|
189
189
|
|
|
190
190
|
context 'when Site.current is set to the same site' do
|
|
191
191
|
before { Site.current = site }
|
|
192
|
-
it {
|
|
192
|
+
it { is_expected.to be_truthy }
|
|
193
193
|
end
|
|
194
194
|
|
|
195
195
|
context 'when Site.current is set to nil' do
|
|
196
196
|
before { Site.current = nil }
|
|
197
|
-
it {
|
|
197
|
+
it { is_expected.to be_falsey }
|
|
198
198
|
end
|
|
199
199
|
|
|
200
200
|
context 'when Site.current is set to a different site' do
|
|
201
201
|
before { Site.current = another_site }
|
|
202
|
-
it {
|
|
202
|
+
it { is_expected.to be_falsey }
|
|
203
203
|
end
|
|
204
204
|
end
|
|
205
205
|
|
|
@@ -207,7 +207,7 @@ module Alchemy
|
|
|
207
207
|
let(:site) {Site.new(name: 'My custom site')}
|
|
208
208
|
|
|
209
209
|
it "returns the path to partial" do
|
|
210
|
-
site.to_partial_path.
|
|
210
|
+
expect(site.to_partial_path).to eq("alchemy/site_layouts/my_custom_site")
|
|
211
211
|
end
|
|
212
212
|
end
|
|
213
213
|
|
|
@@ -215,7 +215,7 @@ module Alchemy
|
|
|
215
215
|
let(:site) {Site.new(name: 'My custom site')}
|
|
216
216
|
|
|
217
217
|
it "returns the name for layout partial" do
|
|
218
|
-
site.layout_partial_name.
|
|
218
|
+
expect(site.layout_partial_name).to eq("my_custom_site")
|
|
219
219
|
end
|
|
220
220
|
end
|
|
221
221
|
|
|
@@ -224,8 +224,8 @@ module Alchemy
|
|
|
224
224
|
let(:definitions) { [{'name' => 'my_custom_site', 'page_layouts' => %w(standard)}] }
|
|
225
225
|
|
|
226
226
|
it "returns layout definition from site_layouts.yml file" do
|
|
227
|
-
Site.
|
|
228
|
-
site.layout_definition.
|
|
227
|
+
allow(Site).to receive(:layout_definitions).and_return(definitions)
|
|
228
|
+
expect(site.layout_definition).to eq(definitions.first)
|
|
229
229
|
end
|
|
230
230
|
end
|
|
231
231
|
|