alchemy_cms 3.0.4 → 3.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (210) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -6
  3. data/Gemfile +4 -7
  4. data/README.md +207 -115
  5. data/alchemy_cms.gemspec +10 -9
  6. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +2 -2
  7. data/app/assets/javascripts/alchemy/alchemy.image_cropper.js.coffee +2 -2
  8. data/app/assets/javascripts/alchemy/alchemy.js +6 -7
  9. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +1 -43
  10. data/app/assets/javascripts/alchemy/alchemy.uploader.js.coffee +1 -1
  11. data/app/assets/stylesheets/alchemy/_mixins.scss +2 -1
  12. data/app/assets/stylesheets/alchemy/buttons.scss +0 -5
  13. data/app/assets/stylesheets/alchemy/dialogs.scss +1 -0
  14. data/app/assets/stylesheets/alchemy/frame.scss +9 -12
  15. data/app/assets/stylesheets/tinymce/skins/alchemy/content.min.css.scss +11 -2
  16. data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +9 -1
  17. data/app/controllers/alchemy/admin/attachments_controller.rb +2 -4
  18. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +34 -38
  19. data/app/controllers/alchemy/api/base_controller.rb +19 -0
  20. data/app/controllers/alchemy/api/contents_controller.rb +35 -0
  21. data/app/controllers/alchemy/api/elements_controller.rb +29 -0
  22. data/app/controllers/alchemy/api/pages_controller.rb +32 -0
  23. data/app/controllers/alchemy/contents_controller.rb +1 -0
  24. data/app/controllers/alchemy/elements_controller.rb +5 -2
  25. data/app/controllers/alchemy/pages_controller.rb +4 -1
  26. data/app/controllers/alchemy/pictures_controller.rb +4 -36
  27. data/app/helpers/alchemy/admin/essences_helper.rb +5 -2
  28. data/app/helpers/alchemy/essences_helper.rb +14 -1
  29. data/app/models/alchemy/content.rb +32 -4
  30. data/app/models/alchemy/element.rb +2 -16
  31. data/app/models/alchemy/element/presenters.rb +2 -2
  32. data/app/models/alchemy/essence_file.rb +5 -0
  33. data/app/models/alchemy/essence_picture.rb +12 -8
  34. data/app/models/alchemy/picture.rb +1 -74
  35. data/app/models/alchemy/picture/transformations.rb +249 -0
  36. data/app/serializers/alchemy/content_serializer.rb +3 -10
  37. data/app/serializers/alchemy/element_serializer.rb +6 -3
  38. data/app/serializers/alchemy/legacy_element_serializer.rb +17 -0
  39. data/app/views/alchemy/admin/dashboard/_sites.html.erb +14 -4
  40. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +8 -5
  41. data/app/views/alchemy/admin/pages/edit.html.erb +9 -9
  42. data/app/views/alchemy/admin/pictures/info.html.erb +2 -3
  43. data/app/views/alchemy/admin/tags/edit.html.erb +1 -1
  44. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +8 -7
  45. data/app/views/alchemy/essences/_essence_boolean_view.html.erb +3 -3
  46. data/app/views/alchemy/essences/_essence_date_editor.html.erb +8 -2
  47. data/app/views/alchemy/essences/_essence_date_view.html.erb +10 -8
  48. data/app/views/alchemy/essences/_essence_file_editor.html.erb +48 -53
  49. data/app/views/alchemy/essences/_essence_file_view.html.erb +5 -5
  50. data/app/views/alchemy/essences/_essence_html_editor.html.erb +5 -4
  51. data/app/views/alchemy/essences/_essence_link_editor.html.erb +17 -15
  52. data/app/views/alchemy/essences/_essence_link_view.html.erb +11 -7
  53. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +4 -2
  54. data/app/views/alchemy/essences/_essence_picture_view.html.erb +4 -2
  55. data/app/views/alchemy/essences/_essence_richtext_view.html.erb +5 -4
  56. data/app/views/alchemy/essences/_essence_select_editor.html.erb +22 -32
  57. data/app/views/alchemy/essences/_essence_text_view.html.erb +7 -6
  58. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +1 -1
  59. data/app/views/layouts/alchemy/admin.html.erb +5 -3
  60. data/config/initializers/inflections.rb +3 -0
  61. data/config/initializers/simple_form.rb +1 -1
  62. data/config/locales/alchemy.en.yml +0 -1
  63. data/config/routes.rb +14 -0
  64. data/lib/alchemy/capistrano.rb +71 -0
  65. data/lib/alchemy/engine.rb +0 -3
  66. data/lib/alchemy/essence.rb +1 -1
  67. data/lib/alchemy/permissions.rb +19 -5
  68. data/lib/alchemy/picture_attributes.rb +1 -1
  69. data/lib/alchemy/test_support/auth_helpers.rb +1 -1
  70. data/lib/alchemy/test_support/essence_shared_examples.rb +37 -22
  71. data/lib/alchemy/test_support/integration_helpers.rb +1 -1
  72. data/lib/alchemy/tinymce.rb +21 -4
  73. data/lib/alchemy/upgrader/three_point_one.rb +43 -0
  74. data/lib/alchemy/upgrader/three_point_zero.rb +13 -0
  75. data/lib/alchemy/version.rb +2 -1
  76. data/lib/rails/generators/alchemy/module/module_generator.rb +30 -0
  77. data/lib/rails/generators/alchemy/module/templates/ability.rb.tt +11 -0
  78. data/lib/rails/generators/alchemy/module/templates/controller.rb.tt +2 -0
  79. data/lib/rails/generators/alchemy/module/templates/module_config.rb.tt +15 -0
  80. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +0 -1
  81. data/lib/rails/templates/alchemy.rb +2 -2
  82. data/lib/tasks/alchemy/db.rake +7 -1
  83. data/spec/controllers/admin/attachments_controller_spec.rb +38 -38
  84. data/spec/controllers/admin/base_controller_spec.rb +18 -18
  85. data/spec/controllers/admin/clipboard_controller_spec.rb +23 -18
  86. data/spec/controllers/admin/contents_controller_spec.rb +33 -27
  87. data/spec/controllers/admin/dashboard_controller_spec.rb +14 -14
  88. data/spec/controllers/admin/elements_controller_spec.rb +125 -105
  89. data/spec/controllers/admin/essence_files_controller_spec.rb +6 -7
  90. data/spec/controllers/admin/essence_pictures_controller_spec.rb +52 -42
  91. data/spec/controllers/admin/languages_controller_spec.rb +3 -3
  92. data/spec/controllers/admin/pages_controller_spec.rb +81 -71
  93. data/spec/controllers/admin/pictures_controller_spec.rb +69 -72
  94. data/spec/controllers/admin/resources_controller_spec.rb +5 -5
  95. data/spec/controllers/admin/trash_controller_spec.rb +15 -12
  96. data/spec/controllers/alchemy/admin/tags_controller_spec.rb +8 -8
  97. data/spec/controllers/alchemy/api/contents_controller_spec.rb +73 -0
  98. data/spec/controllers/alchemy/api/elements_controller_spec.rb +69 -0
  99. data/spec/controllers/alchemy/api/pages_controller_spec.rb +86 -0
  100. data/spec/controllers/attachments_controller_spec.rb +8 -8
  101. data/spec/controllers/contents_controller_spec.rb +22 -0
  102. data/spec/controllers/elements_controller_spec.rb +10 -4
  103. data/spec/controllers/messages_controller_spec.rb +35 -34
  104. data/spec/controllers/pages_controller_spec.rb +37 -28
  105. data/spec/controllers/pictures_controller_spec.rb +90 -23
  106. data/spec/dummy/app/models/dummy_user.rb +0 -4
  107. data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_editor.html.erb +11 -0
  108. data/spec/dummy/config/alchemy/elements.yml +22 -1
  109. data/spec/dummy/config/alchemy/page_layouts.yml +4 -0
  110. data/spec/dummy/config/application.rb +2 -1
  111. data/spec/dummy/config/environments/test.rb +3 -1
  112. data/spec/features/admin/dashboard_spec.rb +41 -6
  113. data/spec/features/admin/language_tree_feature_spec.rb +3 -3
  114. data/spec/features/admin/legacy_page_url_management_spec.rb +1 -1
  115. data/spec/features/admin/link_overlay_spec.rb +7 -7
  116. data/spec/features/admin/locale_select_feature_spec.rb +5 -2
  117. data/spec/features/admin/modules_integration_spec.rb +1 -1
  118. data/spec/features/admin/page_creation_feature_spec.rb +3 -2
  119. data/spec/features/admin/page_editing_feature_spec.rb +66 -79
  120. data/spec/features/admin/picture_library_integration_spec.rb +8 -8
  121. data/spec/features/admin/resources_integration_spec.rb +21 -21
  122. data/spec/features/admin/tinymce_feature_spec.rb +36 -0
  123. data/spec/features/navigation_spec.rb +1 -1
  124. data/spec/features/page_feature_spec.rb +34 -34
  125. data/spec/features/picture_security_spec.rb +4 -4
  126. data/spec/features/security_spec.rb +1 -1
  127. data/spec/features/translation_integration_spec.rb +7 -7
  128. data/spec/helpers/admin/base_helper_spec.rb +51 -49
  129. data/spec/helpers/admin/contents_helper_spec.rb +11 -11
  130. data/spec/helpers/admin/elements_helper_spec.rb +20 -17
  131. data/spec/helpers/admin/essences_helper_spec.rb +42 -11
  132. data/spec/helpers/admin/navigation_helper_spec.rb +64 -54
  133. data/spec/helpers/admin/pages_helper_spec.rb +10 -10
  134. data/spec/helpers/admin/tags_helper_spec.rb +16 -16
  135. data/spec/helpers/base_helper_spec.rb +11 -11
  136. data/spec/helpers/elements_block_helper_spec.rb +24 -24
  137. data/spec/helpers/elements_helper_spec.rb +46 -46
  138. data/spec/helpers/essences_helper_spec.rb +90 -17
  139. data/spec/helpers/pages_helper_spec.rb +53 -53
  140. data/spec/helpers/picture_url_helpers_spec.rb +6 -6
  141. data/spec/helpers/url_helper_spec.rb +32 -32
  142. data/spec/libraries/config_spec.rb +9 -9
  143. data/spec/libraries/controller_actions_spec.rb +14 -14
  144. data/spec/libraries/i18n_spec.rb +6 -6
  145. data/spec/libraries/kaminari/scoped_pagination_url_helper_spec.rb +4 -4
  146. data/spec/libraries/modules_spec.rb +4 -4
  147. data/spec/libraries/mount_point_spec.rb +13 -13
  148. data/spec/libraries/page_layout_spec.rb +24 -24
  149. data/spec/libraries/permissions_spec.rb +97 -80
  150. data/spec/libraries/resource_spec.rb +37 -37
  151. data/spec/libraries/resources_helper_spec.rb +19 -19
  152. data/spec/libraries/shell_spec.rb +17 -17
  153. data/spec/libraries/template_tracker_spec.rb +14 -14
  154. data/spec/libraries/tinymce_spec.rb +8 -8
  155. data/spec/libraries/userstamp_spec.rb +2 -2
  156. data/spec/mailers/messages_spec.rb +4 -4
  157. data/spec/models/attachment_spec.rb +86 -30
  158. data/spec/models/cell_spec.rb +10 -10
  159. data/spec/models/content_spec.rb +106 -46
  160. data/spec/models/element_spec.rb +94 -115
  161. data/spec/models/essence_date_spec.rb +1 -1
  162. data/spec/models/essence_file_spec.rb +4 -4
  163. data/spec/models/essence_picture_spec.rb +56 -25
  164. data/spec/models/essence_richtext_spec.rb +1 -1
  165. data/spec/models/essence_text_spec.rb +7 -7
  166. data/spec/models/language_spec.rb +12 -12
  167. data/spec/models/legacy_page_url_spec.rb +2 -2
  168. data/spec/models/message_spec.rb +12 -5
  169. data/spec/models/page_spec.rb +259 -235
  170. data/spec/models/picture_spec.rb +72 -166
  171. data/spec/models/site_spec.rb +41 -41
  172. data/spec/models/tag_spec.rb +7 -7
  173. data/spec/routing/api_routing_spec.rb +150 -0
  174. data/spec/routing/routing_spec.rb +28 -28
  175. data/spec/spec_helper.rb +6 -5
  176. data/spec/support/hint_examples.rb +5 -5
  177. data/spec/support/transformation_examples.rb +173 -0
  178. data/spec/tasks/helpers_spec.rb +29 -29
  179. data/spec/views/essences/essence_boolean_editor_spec.rb +32 -0
  180. data/spec/views/essences/essence_boolean_view_spec.rb +2 -2
  181. data/spec/views/essences/essence_date_view_spec.rb +1 -1
  182. data/spec/views/essences/essence_link_view_spec.rb +11 -0
  183. data/spec/views/essences/essence_picture_view_spec.rb +56 -11
  184. data/spec/views/essences/essence_richtext_view_spec.rb +12 -0
  185. data/spec/views/essences/essence_text_view_spec.rb +12 -0
  186. data/vendor/assets/javascripts/tinymce/langs/de.js +20 -2
  187. data/vendor/assets/javascripts/tinymce/langs/fr.js +14 -1
  188. data/vendor/assets/javascripts/tinymce/langs/nl.js +22 -4
  189. data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.min.js +1 -1
  190. data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.min.js +1 -1
  191. data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.min.js +1 -1
  192. data/vendor/assets/javascripts/tinymce/plugins/code/plugin.min.js +1 -1
  193. data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.min.js +1 -1
  194. data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.min.js +1 -1
  195. data/vendor/assets/javascripts/tinymce/plugins/hr/plugin.min.js +1 -1
  196. data/vendor/assets/javascripts/tinymce/plugins/link/plugin.min.js +1 -1
  197. data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.min.js +1 -1
  198. data/vendor/assets/javascripts/tinymce/plugins/tabfocus/plugin.min.js +1 -1
  199. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.min.js +1 -1
  200. data/vendor/assets/javascripts/tinymce/themes/modern/theme.min.js +1 -1
  201. data/vendor/assets/javascripts/tinymce/tinymce.min.js +11 -10
  202. metadata +72 -42
  203. data/app/views/alchemy/messages/contact_form_mail.es.text.erb +0 -12
  204. data/config/locales/alchemy.es.yml +0 -958
  205. data/config/locales/alchemy.ru.yml +0 -837
  206. data/config/locales/simple_form.es.yml +0 -6
  207. data/config/locales/simple_form.ru.yml +0 -25
  208. data/lib/rails/generators/alchemy/scaffold/files/alchemy.es.yml +0 -31
  209. data/vendor/assets/javascripts/tinymce/langs/es.js +0 -197
  210. data/vendor/assets/javascripts/tinymce/langs/ru.js +0 -197
@@ -9,129 +9,129 @@ module Alchemy
9
9
 
10
10
  context "with max_images option set to emtpy string" do
11
11
  let(:options) { {max_images: ""} }
12
- it { should eq(nil) }
12
+ it { is_expected.to eq(nil) }
13
13
  end
14
14
 
15
15
  context "with max_images option set to '1'" do
16
16
  let(:options) { {max_images: "1"} }
17
- it { should eq(1) }
17
+ it { is_expected.to eq(1) }
18
18
  end
19
19
 
20
20
  context "with maximum_amount_of_images option set to emtpy string" do
21
21
  let(:options) { {maximum_amount_of_images: ""} }
22
- it { should eq(nil) }
22
+ it { is_expected.to eq(nil) }
23
23
  end
24
24
 
25
25
  context "with maximum_amount_of_images option set to '1'" do
26
26
  let(:options) { {maximum_amount_of_images: "1"} }
27
- it { should eq(1) }
27
+ it { is_expected.to eq(1) }
28
28
  end
29
29
  end
30
30
 
31
31
  describe "#merge_params" do
32
32
  before do
33
- controller.stub(:params).and_return({:first => '1', :second => '2'})
33
+ allow(controller).to receive(:params).and_return({:first => '1', :second => '2'})
34
34
  end
35
35
 
36
36
  it "returns a hash that contains the current params and additional params given as attributes" do
37
- helper.merge_params(:third => '3', :fourth => '4').should == {:first => '1', :second => '2', :third => '3', :fourth => '4'}
37
+ expect(helper.merge_params(:third => '3', :fourth => '4')).to eq({:first => '1', :second => '2', :third => '3', :fourth => '4'})
38
38
  end
39
39
  end
40
40
 
41
41
  describe "#merge_params_without" do
42
42
  before do
43
- controller.stub(:params).and_return({:first => '1', :second => '2'})
43
+ allow(controller).to receive(:params).and_return({:first => '1', :second => '2'})
44
44
  end
45
45
 
46
46
  it "can delete a single param" do
47
- helper.merge_params_without(:second).should == {:first => '1'}
47
+ expect(helper.merge_params_without(:second)).to eq({:first => '1'})
48
48
  end
49
49
 
50
50
  it "can delete several params" do
51
- helper.merge_params_without([:first, :second]).should == {}
51
+ expect(helper.merge_params_without([:first, :second])).to eq({})
52
52
  end
53
53
 
54
54
  it "can delete a param and add new params at the same time" do
55
- helper.merge_params_without([:first], {:third => '3'}).should == {:second => '2', :third => '3'}
55
+ expect(helper.merge_params_without([:first], {:third => '3'})).to eq({:second => '2', :third => '3'})
56
56
  end
57
57
 
58
58
  it "should not change params" do
59
59
  helper.merge_params_without([:first])
60
- controller.params.should == {:first => '1', :second => '2'}
60
+ expect(controller.params).to eq({:first => '1', :second => '2'})
61
61
  end
62
62
  end
63
63
 
64
64
  describe "#merge_params_only" do
65
65
  before do
66
- controller.stub(:params).and_return({:first => '1', :second => '2', :third => '3'})
66
+ allow(controller).to receive(:params).and_return({:first => '1', :second => '2', :third => '3'})
67
67
  end
68
68
 
69
69
  it "can keep a single param" do
70
- helper.merge_params_only(:second).should == {:second => '2'}
70
+ expect(helper.merge_params_only(:second)).to eq({:second => '2'})
71
71
  end
72
72
 
73
73
  it "can keep several params" do
74
- helper.merge_params_only([:first, :second]).should == {:first => '1', :second => '2'}
74
+ expect(helper.merge_params_only([:first, :second])).to eq({:first => '1', :second => '2'})
75
75
  end
76
76
 
77
77
  it "can keep a param and add new params at the same time" do
78
- helper.merge_params_only([:first], {:third => '3'}).should == {:first => '1', :third => '3'}
78
+ expect(helper.merge_params_only([:first], {:third => '3'})).to eq({:first => '1', :third => '3'})
79
79
  end
80
80
 
81
81
  it "should not change params" do
82
82
  helper.merge_params_only([:first])
83
- controller.params.should == {:first => '1', :second => '2', :third => '3'}
83
+ expect(controller.params).to eq({:first => '1', :second => '2', :third => '3'})
84
84
  end
85
85
  end
86
86
 
87
87
  describe '#toolbar_button' do
88
88
  context "with permission" do
89
- before { helper.stub(:can?).and_return(true) }
89
+ before { allow(helper).to receive(:can?).and_return(true) }
90
90
 
91
91
  it "renders a toolbar button" do
92
- helper.toolbar_button(
92
+ expect(helper.toolbar_button(
93
93
  url: admin_dashboard_path
94
- ).should match /<div.+class="button_with_label/
94
+ )).to match /<div.+class="button_with_label/
95
95
  end
96
96
  end
97
97
 
98
98
  context "without permission" do
99
- before { helper.stub(:can?).and_return(false) }
99
+ before { allow(helper).to receive(:can?).and_return(false) }
100
100
 
101
101
  it "returns empty string" do
102
- helper.toolbar_button(
102
+ expect(helper.toolbar_button(
103
103
  url: admin_dashboard_path
104
- ).should be_empty
104
+ )).to be_empty
105
105
  end
106
106
  end
107
107
 
108
108
  context "with disabled permission check" do
109
- before { helper.stub(:can?).and_return(false) }
109
+ before { allow(helper).to receive(:can?).and_return(false) }
110
110
 
111
111
  it "returns the button" do
112
- helper.toolbar_button(
112
+ expect(helper.toolbar_button(
113
113
  url: admin_dashboard_path,
114
114
  skip_permission_check: true
115
- ).should match /<div.+class="button_with_label/
115
+ )).to match /<div.+class="button_with_label/
116
116
  end
117
117
  end
118
118
 
119
119
  context "with empty permission option" do
120
- before { helper.stub(:can?).and_return(true) }
120
+ before { allow(helper).to receive(:can?).and_return(true) }
121
121
 
122
122
  it "returns reads the permission from url" do
123
- helper.should_receive(:permission_array_from_url)
124
- helper.toolbar_button(
123
+ expect(helper).to receive(:permission_array_from_url)
124
+ expect(helper.toolbar_button(
125
125
  url: admin_dashboard_path,
126
126
  if_permitted_to: ''
127
- ).should_not be_empty
127
+ )).not_to be_empty
128
128
  end
129
129
  end
130
130
 
131
131
  context "with overlay option set to false" do
132
132
  before do
133
- helper.stub(:can?).and_return(true)
134
- helper.should_receive(:permission_array_from_url)
133
+ allow(helper).to receive(:can?).and_return(true)
134
+ expect(helper).to receive(:permission_array_from_url)
135
135
  end
136
136
 
137
137
  it "renders a normal link" do
@@ -139,16 +139,16 @@ module Alchemy
139
139
  url: admin_dashboard_path,
140
140
  overlay: false
141
141
  )
142
- button.should match /<a.+href="#{admin_dashboard_path}"/
143
- button.should_not match /data-alchemy-overlay/
142
+ expect(button).to match /<a.+href="#{admin_dashboard_path}"/
143
+ expect(button).not_to match /data-alchemy-overlay/
144
144
  end
145
145
  end
146
146
  end
147
147
 
148
148
  describe "#translations_for_select" do
149
149
  it "should return an Array of Arrays with available locales" do
150
- Alchemy::I18n.stub(:available_locales).and_return([:de, :en, :cz, :it])
151
- expect(helper.translations_for_select).to have(4).items
150
+ allow(Alchemy::I18n).to receive(:available_locales).and_return([:de, :en, :cz, :it])
151
+ expect(helper.translations_for_select.size).to eq(4)
152
152
  end
153
153
  end
154
154
 
@@ -161,14 +161,14 @@ module Alchemy
161
161
  let(:clipboard_items) { [element] }
162
162
 
163
163
  it "should include select options with the display name and preview text" do
164
- element.stub(:display_name_with_preview_text).and_return('Name with Preview text')
164
+ allow(element).to receive(:display_name_with_preview_text).and_return('Name with Preview text')
165
165
  expect(helper.clipboard_select_tag_options(clipboard_items)).to have_selector('option', text: 'Name with Preview text')
166
166
  end
167
167
 
168
168
  context "when @page can have cells" do
169
- before { page.stub(:can_have_cells?).and_return(true) }
169
+ before { allow(page).to receive(:can_have_cells?).and_return(true) }
170
170
  it "should group the elements in the clipboard by cell" do
171
- helper.should_receive(:grouped_elements_for_select).and_return({})
171
+ expect(helper).to receive(:grouped_elements_for_select).and_return({})
172
172
  helper.clipboard_select_tag_options(clipboard_items)
173
173
  end
174
174
  end
@@ -188,7 +188,7 @@ module Alchemy
188
188
  subject { button_with_confirm }
189
189
 
190
190
  it "renders a button tag with a data attribute for confirm dialog" do
191
- should have_selector('button[data-alchemy-confirm]')
191
+ is_expected.to have_selector('button[data-alchemy-confirm]')
192
192
  end
193
193
  end
194
194
 
@@ -196,11 +196,11 @@ module Alchemy
196
196
  subject { delete_button('/admin/pages') }
197
197
 
198
198
  it "renders a button tag" do
199
- should have_selector('button')
199
+ is_expected.to have_selector('button')
200
200
  end
201
201
 
202
202
  it "returns a form tag with method=delete" do
203
- should have_selector('form input[name="_method"][value="delete"]')
203
+ is_expected.to have_selector('form input[name="_method"][value="delete"]')
204
204
  end
205
205
  end
206
206
 
@@ -211,11 +211,11 @@ module Alchemy
211
211
  let(:now) { Time.now }
212
212
 
213
213
  it "renders a date field" do
214
- should have_selector("input[type='date']")
214
+ is_expected.to have_selector("input[type='date']")
215
215
  end
216
216
 
217
217
  it "sets default date as value" do
218
- should have_selector("input[value='#{::I18n.l(now, format: :datepicker)}']")
218
+ is_expected.to have_selector("input[value='#{::I18n.l(now, format: :datepicker)}']")
219
219
  end
220
220
 
221
221
  context 'with date stored on object' do
@@ -223,7 +223,7 @@ module Alchemy
223
223
  let(:essence) { EssenceDate.new(date: date) }
224
224
 
225
225
  it "sets this date as value" do
226
- should have_selector("input[value='#{::I18n.l(date, format: :datepicker)}']")
226
+ is_expected.to have_selector("input[value='#{::I18n.l(date, format: :datepicker)}']")
227
227
  end
228
228
  end
229
229
  end
@@ -231,21 +231,21 @@ module Alchemy
231
231
  describe '#current_alchemy_user_name' do
232
232
  subject { helper.current_alchemy_user_name }
233
233
 
234
- before { helper.stub(current_alchemy_user: user) }
234
+ before { expect(helper).to receive(:current_alchemy_user).and_return(user) }
235
235
 
236
236
  context 'with a user having a `alchemy_display_name` method' do
237
237
  let(:user) { double('User', alchemy_display_name: 'Peter Schroeder') }
238
238
 
239
239
  it "Returns a span showing the name of the currently logged in user." do
240
- should have_content("#{Alchemy::I18n.t('Logged in as')} Peter Schroeder")
241
- should have_selector("span.current-user-name")
240
+ is_expected.to have_content("#{Alchemy::I18n.t('Logged in as')} Peter Schroeder")
241
+ is_expected.to have_selector("span.current-user-name")
242
242
  end
243
243
  end
244
244
 
245
245
  context 'with a user not having a `alchemy_display_name` method' do
246
246
  let(:user) { double('User', name: 'Peter Schroeder') }
247
247
 
248
- it { should be_nil }
248
+ it { is_expected.to be_nil }
249
249
  end
250
250
  end
251
251
 
@@ -257,7 +257,9 @@ module Alchemy
257
257
  end
258
258
 
259
259
  context 'if the expression from config is nil' do
260
- before { Alchemy::Config.stub(get: {link_url: nil}) }
260
+ before do
261
+ expect(Alchemy::Config).to receive(:get).and_return({link_url: nil})
262
+ end
261
263
 
262
264
  it "returns the default expression" do
263
265
  expect(subject).to_not be_nil
@@ -15,31 +15,31 @@ describe Alchemy::Admin::ContentsHelper do
15
15
  subject { helper.render_content_name(content) }
16
16
 
17
17
  it "returns the content name" do
18
- should == "Intro"
18
+ is_expected.to eq("Intro")
19
19
  end
20
20
 
21
21
  context 'if content is nil' do
22
22
  let(:content) { nil }
23
23
 
24
24
  it "returns nil" do
25
- should be_nil
25
+ is_expected.to be_nil
26
26
  end
27
27
  end
28
28
 
29
29
  context 'with missing description' do
30
- before { content.stub(description: {}) }
30
+ before { expect(content).to receive(:description).and_return({}) }
31
31
 
32
32
  it "renders a warning" do
33
- should have_selector('span.warning')
34
- should have_content('Intro')
33
+ is_expected.to have_selector('span.warning')
34
+ is_expected.to have_content('Intro')
35
35
  end
36
36
  end
37
37
 
38
38
  context 'with validations' do
39
- before { content.stub(has_validations?: true) }
39
+ before { expect(content).to receive(:has_validations?).and_return(true) }
40
40
 
41
41
  it "show a validation indicator" do
42
- should have_selector('.validation_indicator')
42
+ is_expected.to have_selector('.validation_indicator')
43
43
  end
44
44
  end
45
45
  end
@@ -48,8 +48,8 @@ describe Alchemy::Admin::ContentsHelper do
48
48
  subject { helper.render_new_content_link(element) }
49
49
 
50
50
  it "renders a link to add new content to element" do
51
- helper.stub(:render_icon).and_return('')
52
- should match(/a.+href.*admin\/elements\/#{element.id}\/contents\/new/m)
51
+ allow(helper).to receive(:render_icon).and_return('')
52
+ is_expected.to match(/a.+href.*admin\/elements\/#{element.id}\/contents\/new/m)
53
53
  end
54
54
  end
55
55
 
@@ -57,8 +57,8 @@ describe Alchemy::Admin::ContentsHelper do
57
57
  subject { helper.render_create_content_link(element, 'headline') }
58
58
 
59
59
  it "should render a link to create a content in element" do
60
- helper.stub(:render_icon).and_return('')
61
- should have_selector('a.new_content_link[data-method="post"]')
60
+ allow(helper).to receive(:render_icon).and_return('')
61
+ is_expected.to have_selector('a.new_content_link[data-method="post"]')
62
62
  end
63
63
  end
64
64
 
@@ -8,12 +8,12 @@ module Alchemy
8
8
 
9
9
  context "partial rendering" do
10
10
  it "should render an element editor partial" do
11
- should_receive(:render_element).with(element, :editor)
12
- render_editor(element)
11
+ expect(helper).to receive(:render_element).with(element, :editor)
12
+ helper.render_editor(element)
13
13
  end
14
14
 
15
15
  it "should render a picture gallery editor partial" do
16
- render_picture_gallery_editor(element).should match(/class=".+picture_gallery_editor"/)
16
+ expect(render_picture_gallery_editor(element)).to match(/class=".+picture_gallery_editor"/)
17
17
  end
18
18
  end
19
19
 
@@ -26,29 +26,32 @@ module Alchemy
26
26
  }
27
27
 
28
28
  before do
29
- page.stub(layout_description: {'name' => "foo", 'cells' => ["foo_cell", "empty_cell"]})
30
- cell_descriptions = [
31
- {'name' => "foo_cell", 'elements' => ["1", "2"]},
32
- {'name' => 'empty_cell', 'elements' => []}
33
- ]
34
- Cell.stub(:definitions).and_return(cell_descriptions)
29
+ allow(page).to receive(:layout_description).and_return({
30
+ 'name' => "foo",
31
+ 'cells' => ["foo_cell"]
32
+ })
33
+ cell_descriptions = [{
34
+ 'name' => "foo_cell",
35
+ 'elements' => ["1", "2"]
36
+ }]
37
+ allow(Cell).to receive(:definitions).and_return(cell_descriptions)
35
38
  helper.instance_variable_set('@page', page)
36
39
  end
37
40
 
38
41
  it "should return array of elements grouped by cell for select_tag helper" do
39
- helper.grouped_elements_for_select(elements).should include("Foo cell" => [["1", "1#foo_cell"], ["2", "2#foo_cell"]])
42
+ expect(helper.grouped_elements_for_select(elements)).to include("Foo cell" => [["1", "1#foo_cell"], ["2", "2#foo_cell"]])
40
43
  end
41
44
 
42
45
  context "with empty elements array" do
43
46
  it "should return an empty string" do
44
- helper.grouped_elements_for_select([]).should == ""
47
+ expect(helper.grouped_elements_for_select([])).to eq("")
45
48
  end
46
49
  end
47
50
 
48
51
  context "with empty cell definitions" do
49
52
  it "should return an empty string" do
50
- page.stub(layout_description: {'name' => "foo"})
51
- helper.grouped_elements_for_select(elements).should == ""
53
+ allow(page).to receive(:layout_description).and_return({'name' => "foo"})
54
+ expect(helper.grouped_elements_for_select(elements)).to eq("")
52
55
  end
53
56
  end
54
57
 
@@ -69,8 +72,8 @@ module Alchemy
69
72
  end
70
73
 
71
74
  it "should return a array for option tags" do
72
- helper.elements_for_select(element_objects).should include(['Element 1', 'element_1'])
73
- helper.elements_for_select(element_objects).should include(['Element 2', 'element_2'])
75
+ expect(helper.elements_for_select(element_objects)).to include(['Element 1', 'element_1'])
76
+ expect(helper.elements_for_select(element_objects)).to include(['Element 2', 'element_2'])
74
77
  end
75
78
  end
76
79
 
@@ -85,11 +88,11 @@ module Alchemy
85
88
  subject { helper.elements_for_select(element_descriptions) }
86
89
 
87
90
  it "should return a array for option tags" do
88
- subject.should include(['Headline', 'headline'])
91
+ expect(subject).to include(['Headline', 'headline'])
89
92
  end
90
93
 
91
94
  it "should render the elements display name" do
92
- Element.should_receive(:display_name_for).with('headline')
95
+ expect(Element).to receive(:display_name_for).with('headline')
93
96
  subject
94
97
  end
95
98
  end
@@ -15,7 +15,7 @@ describe Alchemy::Admin::EssencesHelper do
15
15
  describe '#render_essence_editor' do
16
16
  it "should render an essence editor" do
17
17
  content = element.content_by_name('intro')
18
- helper.render_essence_editor(content).should match(/input.+type="text".+value="hello!/)
18
+ expect(helper.render_essence_editor(content)).to match(/input.+type="text".+value="hello!/)
19
19
  end
20
20
  end
21
21
 
@@ -25,15 +25,15 @@ describe Alchemy::Admin::EssencesHelper do
25
25
  let(:content) { 'intro' }
26
26
 
27
27
  it "renders an essence editor by given name" do
28
- should match(/input.+type="text".+value="hello!/)
28
+ is_expected.to match(/input.+type="text".+value="hello!/)
29
29
  end
30
30
 
31
31
  context 'when element is nil' do
32
32
  let(:element) { nil }
33
33
 
34
34
  it "displays a warning" do
35
- should have_selector(".content_editor_error")
36
- should have_content("No element given.")
35
+ is_expected.to have_selector(".content_editor_error")
36
+ is_expected.to have_content("No element given.")
37
37
  end
38
38
  end
39
39
 
@@ -41,7 +41,7 @@ describe Alchemy::Admin::EssencesHelper do
41
41
  let(:content) { 'sputz' }
42
42
 
43
43
  it "displays a warning" do
44
- should have_selector(".content_editor.missing")
44
+ is_expected.to have_selector(".content_editor.missing")
45
45
  end
46
46
  end
47
47
  end
@@ -62,13 +62,13 @@ describe Alchemy::Admin::EssencesHelper do
62
62
 
63
63
  context "with no arguments given" do
64
64
  it "should return options for select with all pages ordered by lft" do
65
- helper.pages_for_select.should match(/option.*Page B.*Page A/m)
65
+ expect(helper.pages_for_select).to match(/option.*Page B.*Page A/m)
66
66
  end
67
67
 
68
68
  it "should return options for select with nested page names" do
69
69
  page_c
70
70
  output = helper.pages_for_select
71
- output.should match(/option.*Startseite.*>&nbsp;&nbsp;Page B.*>&nbsp;&nbsp;&nbsp;&nbsp;Page C.*>&nbsp;&nbsp;Page A/m)
71
+ expect(output).to match(/option.*Startseite.*>&nbsp;&nbsp;Page B.*>&nbsp;&nbsp;&nbsp;&nbsp;Page C.*>&nbsp;&nbsp;Page A/m)
72
72
  end
73
73
  end
74
74
 
@@ -80,13 +80,13 @@ describe Alchemy::Admin::EssencesHelper do
80
80
 
81
81
  it "should return options for select with only these pages" do
82
82
  output = helper.pages_for_select(@pages)
83
- output.should match(/#{@pages.collect(&:name).join('.*')}/m)
84
- output.should_not match(/Page A/m)
83
+ expect(output).to match(/#{@pages.collect(&:name).join('.*')}/m)
84
+ expect(output).not_to match(/Page A/m)
85
85
  end
86
86
 
87
87
  it "should not nest the page names" do
88
88
  output = helper.pages_for_select(@pages)
89
- output.should_not match(/option.*&nbsp;/m)
89
+ expect(output).not_to match(/option.*&nbsp;/m)
90
90
  end
91
91
  end
92
92
  end
@@ -99,11 +99,42 @@ describe Alchemy::Admin::EssencesHelper do
99
99
  end
100
100
 
101
101
  context 'when given content has no ingredient' do
102
- before { content.stub(:ingredient).and_return(nil) }
102
+ before { allow(content).to receive(:ingredient).and_return(nil) }
103
+
103
104
  it "should return nil" do
104
105
  expect(helper.essence_picture_thumbnail(content, {})).to eq(nil)
105
106
  end
106
107
  end
108
+
109
+ context 'when the picture given has a size of 140x169 and it should be cropped to 250x250' do
110
+ before do
111
+ allow(content.essence).to receive(:image_file_width).and_return(140)
112
+ allow(content.essence).to receive(:image_file_height).and_return(169)
113
+ end
114
+
115
+ it 'the thumbnail url should contain 77 and 93 as thumbnail width and height' do
116
+ expect(helper.essence_picture_thumbnail(content, {image_size: "250x250", crop: true})).to match(/77x93/)
117
+ end
118
+
119
+ it 'the thumbnail url should contain 77 and 93 as thumbnail width and height' do
120
+ expect(helper.essence_picture_thumbnail(content, {image_size: "250x250"})).to match(/77x93/)
121
+ end
122
+ end
123
+
124
+ context 'when the picture given has a size of 300x50 and it should be cropped/resized to 225x175' do
125
+ before do
126
+ allow(content.essence).to receive(:image_file_width).and_return(300)
127
+ allow(content.essence).to receive(:image_file_height).and_return(50)
128
+ end
129
+
130
+ it 'the thumbnail url should contain 111x25 as thumbnail width and height' do
131
+ expect(helper.essence_picture_thumbnail(content, { size: "225x175", crop: true})).to match(/111x25/)
132
+ end
133
+
134
+ it 'the thumbnail url should contain 111x19 as thumbnail width and height' do
135
+ expect(helper.essence_picture_thumbnail(content, { size: "225x175"})).to match(/111x19/)
136
+ end
137
+ end
107
138
  end
108
139
 
109
140
  end