alchemy_cms 2.6.3 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. checksums.yaml +4 -4
  2. data/.simplecov +14 -0
  3. data/.travis.yml +1 -1
  4. data/Gemfile +7 -6
  5. data/README.md +15 -5
  6. data/alchemy_cms.gemspec +3 -2
  7. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +9 -17
  8. data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +70 -0
  9. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +80 -0
  10. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +43 -19
  11. data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +3 -1
  12. data/app/assets/javascripts/alchemy/alchemy.js +4 -2
  13. data/app/assets/javascripts/alchemy/alchemy.onload.js.coffee +1 -1
  14. data/app/assets/javascripts/alchemy/alchemy.spinner.js.coffee +14 -0
  15. data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee.erb +96 -0
  16. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +22 -0
  17. data/app/assets/javascripts/alchemy/alchemy.windows.js.coffee +28 -17
  18. data/app/assets/stylesheets/alchemy/base.scss +6 -0
  19. data/app/assets/stylesheets/alchemy/elements.scss +2 -28
  20. data/app/assets/stylesheets/alchemy/errors.scss +1 -1
  21. data/app/assets/stylesheets/alchemy/menubar.css.scss +2 -0
  22. data/app/assets/stylesheets/alchemy/sitemap.scss +21 -34
  23. data/app/assets/stylesheets/alchemy/tables.scss +13 -3
  24. data/app/controllers/alchemy/admin/attachments_controller.rb +10 -5
  25. data/app/controllers/alchemy/admin/base_controller.rb +19 -0
  26. data/app/controllers/alchemy/admin/contents_controller.rb +1 -4
  27. data/app/controllers/alchemy/admin/dashboard_controller.rb +2 -1
  28. data/app/controllers/alchemy/admin/elements_controller.rb +1 -1
  29. data/app/controllers/alchemy/admin/essence_files_controller.rb +1 -1
  30. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +70 -56
  31. data/app/controllers/alchemy/admin/pages_controller.rb +37 -114
  32. data/app/controllers/alchemy/admin/pictures_controller.rb +5 -12
  33. data/app/controllers/alchemy/admin/resources_controller.rb +3 -1
  34. data/app/controllers/alchemy/admin/trash_controller.rb +1 -1
  35. data/app/controllers/alchemy/attachments_controller.rb +1 -1
  36. data/app/controllers/alchemy/base_controller.rb +3 -15
  37. data/app/controllers/alchemy/messages_controller.rb +4 -10
  38. data/app/controllers/alchemy/pages_controller.rb +6 -6
  39. data/app/controllers/alchemy/passwords_controller.rb +1 -1
  40. data/app/controllers/alchemy/user_sessions_controller.rb +1 -1
  41. data/app/helpers/alchemy/admin/base_helper.rb +49 -230
  42. data/app/helpers/alchemy/admin/contents_helper.rb +5 -1
  43. data/app/helpers/alchemy/admin/elements_helper.rb +19 -47
  44. data/app/helpers/alchemy/admin/essences_helper.rb +59 -17
  45. data/app/helpers/alchemy/admin/navigation_helper.rb +204 -0
  46. data/app/helpers/alchemy/admin/pages_helper.rb +22 -79
  47. data/app/helpers/alchemy/admin/pictures_helper.rb +1 -1
  48. data/app/helpers/alchemy/admin/tags_helper.rb +42 -0
  49. data/app/helpers/alchemy/base_helper.rb +0 -11
  50. data/app/helpers/alchemy/elements_helper.rb +48 -25
  51. data/app/helpers/alchemy/essences_helper.rb +0 -20
  52. data/app/helpers/alchemy/pages_helper.rb +18 -14
  53. data/app/helpers/alchemy/url_helper.rb +1 -0
  54. data/app/mailers/alchemy/messages.rb +4 -6
  55. data/app/models/alchemy/attachment.rb +3 -0
  56. data/app/models/alchemy/cell.rb +33 -35
  57. data/app/models/alchemy/content.rb +20 -111
  58. data/app/models/alchemy/content/factory.rb +188 -0
  59. data/app/models/alchemy/element.rb +51 -200
  60. data/app/models/alchemy/element/definitions.rb +52 -0
  61. data/app/models/alchemy/element/presenters.rb +87 -0
  62. data/app/models/alchemy/essence_date.rb +1 -1
  63. data/app/models/alchemy/essence_file.rb +6 -7
  64. data/app/models/alchemy/essence_picture.rb +19 -4
  65. data/app/models/alchemy/message.rb +18 -14
  66. data/app/models/alchemy/page.rb +120 -214
  67. data/app/models/alchemy/page/elements.rb +145 -36
  68. data/app/models/alchemy/page/natures.rb +90 -0
  69. data/app/models/alchemy/page/scopes.rb +93 -0
  70. data/app/models/alchemy/page/users.rb +25 -0
  71. data/app/models/alchemy/picture.rb +15 -0
  72. data/app/models/alchemy/site.rb +15 -1
  73. data/app/models/alchemy/site/layout.rb +38 -0
  74. data/app/models/alchemy/user.rb +13 -3
  75. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +7 -7
  76. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +8 -8
  77. data/app/views/alchemy/admin/attachments/_tag_list.html.erb +1 -16
  78. data/app/views/alchemy/admin/attachments/destroy.js.erb +1 -4
  79. data/app/views/alchemy/admin/contents/create.js.erb +1 -1
  80. data/app/views/alchemy/admin/dashboard/index.html.erb +14 -13
  81. data/app/views/alchemy/admin/elements/_element_head.html.erb +7 -7
  82. data/app/views/alchemy/admin/elements/_refresh_editor.js.erb +10 -0
  83. data/app/views/alchemy/admin/elements/create.js.erb +44 -44
  84. data/app/views/alchemy/admin/elements/fold.js.erb +22 -26
  85. data/app/views/alchemy/admin/elements/trash.js.erb +1 -1
  86. data/app/views/alchemy/admin/elements/update.js.erb +22 -25
  87. data/app/views/alchemy/admin/essence_files/assign.js.erb +8 -3
  88. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +14 -12
  89. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +22 -39
  90. data/app/views/alchemy/admin/pages/_page.html.erb +73 -80
  91. data/app/views/alchemy/admin/pages/destroy.js.erb +2 -2
  92. data/app/views/alchemy/admin/pages/edit.html.erb +21 -18
  93. data/app/views/alchemy/admin/pages/fold.js.erb +1 -0
  94. data/app/views/alchemy/admin/pages/info.html.erb +32 -0
  95. data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +11 -13
  96. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +20 -20
  97. data/app/views/alchemy/admin/partials/_sub_navigation.html.erb +8 -0
  98. data/app/views/alchemy/admin/partials/_toolbar_button.html.erb +25 -0
  99. data/app/views/alchemy/admin/partials/_upload_form.html.erb +15 -15
  100. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +39 -39
  101. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +10 -10
  102. data/app/views/alchemy/admin/pictures/_tag_list.html.erb +1 -16
  103. data/app/views/alchemy/admin/resources/destroy.js.erb +1 -1
  104. data/app/views/alchemy/base/500.html.erb +1 -1
  105. data/app/views/alchemy/base/permission_denied.js.erb +1 -1
  106. data/app/views/alchemy/base/redirect.js.erb +1 -1
  107. data/app/views/alchemy/essences/_essence_link_editor.html.erb +1 -1
  108. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +1 -1
  109. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +1 -1
  110. data/app/views/alchemy/essences/_essence_text_editor.html.erb +1 -1
  111. data/app/views/alchemy/essences/{_essence_picture_tools.html.erb → shared/_essence_picture_tools.html.erb} +5 -5
  112. data/app/views/alchemy/essences/{_linkable_essence_tools.html.erb → shared/_linkable_essence_tools.html.erb} +0 -0
  113. data/app/views/alchemy/messages/contact_form_mail.de.text.erb +12 -0
  114. data/app/views/alchemy/messages/contact_form_mail.en.text.erb +12 -0
  115. data/app/views/alchemy/notifications/reset_password_instructions.de.text.erb +1 -1
  116. data/app/views/alchemy/notifications/reset_password_instructions.en.text.erb +2 -2
  117. data/app/views/alchemy/pages/sitemap.xml.erb +3 -5
  118. data/app/views/alchemy/user_sessions/leave.html.erb +1 -1
  119. data/app/views/layouts/alchemy/admin.html.erb +4 -2
  120. data/app/views/layouts/alchemy/sitemap.xml.erb +1 -1
  121. data/bin/alchemy +7 -13
  122. data/config/alchemy/config.yml +1 -0
  123. data/config/authorization_rules.rb +2 -3
  124. data/config/initializers/dragonfly.rb +2 -0
  125. data/config/locales/alchemy.de.yml +8 -9
  126. data/config/locales/alchemy.en.yml +7 -4
  127. data/config/routes.rb +3 -0
  128. data/db/migrate/{20130214233001_alchemy_two_point_five.rb → 20130827094554_alchemy_two_point_six.rb} +29 -6
  129. data/lib/alchemy/auth/engine.rb +9 -0
  130. data/lib/alchemy/capistrano.rb +37 -12
  131. data/lib/alchemy/config.rb +48 -35
  132. data/lib/alchemy/engine.rb +35 -6
  133. data/lib/alchemy/essence.rb +25 -29
  134. data/lib/alchemy/ferret/search.rb +86 -0
  135. data/lib/alchemy/{scoped_pagination_url_helper.rb → kaminari/scoped_pagination_url_helper.rb} +0 -0
  136. data/lib/alchemy/logger.rb +3 -4
  137. data/lib/alchemy/page_layout.rb +124 -55
  138. data/lib/alchemy/resource.rb +0 -10
  139. data/lib/alchemy/resources_helper.rb +0 -5
  140. data/lib/alchemy/seeder.rb +1 -32
  141. data/lib/alchemy/shell.rb +6 -1
  142. data/lib/alchemy/tinymce.rb +41 -32
  143. data/lib/alchemy/upgrader.rb +3 -1
  144. data/lib/alchemy/upgrader/two_point_five.rb +15 -8
  145. data/lib/alchemy/upgrader/two_point_one.rb +10 -10
  146. data/lib/alchemy/upgrader/two_point_two.rb +96 -51
  147. data/lib/alchemy/version.rb +1 -1
  148. data/lib/alchemy_cms.rb +5 -46
  149. data/lib/rails/generators/alchemy/deploy_script/templates/deploy.rb.tt +1 -1
  150. data/lib/rails/generators/alchemy/devise/devise_generator.rb +9 -4
  151. data/lib/rails/generators/alchemy/essence/essence_generator.rb +7 -6
  152. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +1 -1
  153. data/lib/rails/generators/alchemy/scaffold/files/_standard.html.erb +1 -0
  154. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +1 -0
  155. data/lib/rails/generators/alchemy/site_layouts/site_layouts_generator.rb +23 -0
  156. data/lib/rails/generators/alchemy/site_layouts/templates/layout.html.erb +1 -0
  157. data/lib/rails/generators/alchemy/site_layouts/templates/layout.html.haml +1 -0
  158. data/lib/rails/generators/alchemy/site_layouts/templates/layout.html.slim +1 -0
  159. data/lib/rails/templates/alchemy.rb +2 -2
  160. data/lib/tasks/alchemy/db.rake +3 -1
  161. data/lib/tasks/alchemy/tidy.rake +82 -0
  162. data/lib/tasks/alchemy/upgrade.rake +2 -1
  163. data/spec/controllers/admin/attachments_controller_spec.rb +124 -0
  164. data/spec/controllers/admin/base_controller_spec.rb +35 -0
  165. data/spec/controllers/admin/clipboard_controller_spec.rb +1 -1
  166. data/spec/controllers/admin/contents_controller_spec.rb +17 -26
  167. data/spec/controllers/admin/dashboard_controller_spec.rb +121 -0
  168. data/spec/controllers/admin/elements_controller_spec.rb +1 -1
  169. data/spec/controllers/admin/essence_files_controller_spec.rb +67 -0
  170. data/spec/controllers/admin/essence_pictures_controller_spec.rb +161 -0
  171. data/spec/controllers/admin/languages_controller_spec.rb +1 -1
  172. data/spec/controllers/admin/layoutpages_controller_spec.rb +28 -0
  173. data/spec/controllers/admin/pages_controller_spec.rb +164 -118
  174. data/spec/controllers/admin/pictures_controller_spec.rb +89 -0
  175. data/spec/controllers/admin/trash_controller_spec.rb +21 -31
  176. data/spec/controllers/admin/users_controller_spec.rb +114 -85
  177. data/spec/controllers/attachments_controller_spec.rb +6 -2
  178. data/spec/controllers/base_controller_spec.rb +22 -0
  179. data/spec/controllers/elements_controller_spec.rb +1 -1
  180. data/spec/controllers/messages_controller_spec.rb +200 -0
  181. data/spec/controllers/pictures_controller_spec.rb +1 -1
  182. data/spec/controllers/user_sessions_controller_spec.rb +7 -6
  183. data/spec/controllers/users_controller_spec.rb +2 -2
  184. data/spec/dummy/config/alchemy/cells.yml +2 -0
  185. data/spec/dummy/config/application.rb +19 -8
  186. data/spec/dummy/db/migrate/{20130214233001_alchemy_two_point_five.rb → 20130827094554_alchemy_two_point_six.rb} +29 -6
  187. data/spec/dummy/db/schema.rb +1 -1
  188. data/spec/fast_specs.rb +15 -0
  189. data/spec/helpers/admin/base_helper_spec.rb +53 -34
  190. data/spec/helpers/admin/contents_helper_spec.rb +15 -7
  191. data/spec/helpers/admin/elements_helper_spec.rb +79 -34
  192. data/spec/helpers/admin/essences_helper_spec.rb +45 -31
  193. data/spec/helpers/admin/navigation_helper_spec.rb +204 -0
  194. data/spec/helpers/admin/pages_helper_spec.rb +25 -15
  195. data/spec/helpers/admin/tags_helper_spec.rb +62 -2
  196. data/spec/helpers/elements_helper_spec.rb +202 -138
  197. data/spec/helpers/pages_helper_spec.rb +48 -0
  198. data/spec/helpers/url_helper_spec.rb +7 -0
  199. data/spec/libraries/config_spec.rb +110 -3
  200. data/spec/libraries/essence_spec.rb +29 -9
  201. data/spec/libraries/page_layout_spec.rb +134 -0
  202. data/spec/libraries/resource_spec.rb +3 -16
  203. data/spec/libraries/resources_helper_spec.rb +4 -8
  204. data/spec/libraries/shell_spec.rb +1 -0
  205. data/spec/libraries/tinymce_spec.rb +61 -0
  206. data/spec/mailers/messages_spec.rb +23 -0
  207. data/spec/models/attachment_spec.rb +45 -0
  208. data/spec/models/cell_spec.rb +62 -9
  209. data/spec/models/content_spec.rb +110 -28
  210. data/spec/models/element_spec.rb +275 -253
  211. data/spec/models/essence_date_spec.rb +25 -0
  212. data/spec/models/essence_file_spec.rb +23 -0
  213. data/spec/models/essence_html_spec.rb +13 -0
  214. data/spec/models/essence_picture_spec.rb +16 -0
  215. data/spec/models/essence_text_spec.rb +29 -0
  216. data/spec/models/language_spec.rb +34 -0
  217. data/spec/models/message_spec.rb +43 -0
  218. data/spec/models/page_spec.rb +726 -567
  219. data/spec/models/picture_spec.rb +98 -0
  220. data/spec/models/site_spec.rb +60 -2
  221. data/spec/models/tag_spec.rb +31 -0
  222. data/spec/models/user_spec.rb +4 -4
  223. data/spec/spec_helper.rb +49 -58
  224. data/spec/support/alchemy/controller_helpers.rb +35 -0
  225. data/spec/support/alchemy/{specs_helpers.rb → integration_helpers.rb} +4 -8
  226. data/spec/{factories.rb → support/factories.rb} +11 -1
  227. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +2 -8
  228. metadata +166 -106
  229. data/Guardfile +0 -16
  230. data/app/assets/javascripts/alchemy/alchemy.dirty.js +0 -93
  231. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js +0 -122
  232. data/app/models/alchemy/tree_node.rb +0 -4
  233. data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -3
  234. data/app/views/alchemy/admin/partials/_sub_navigation_tab.html.erb +0 -8
  235. data/app/views/alchemy/messages/contact_form_mail.text.erb +0 -12
  236. data/config/initializers/kaminari_config.rb +0 -9
  237. data/db/migrate/20130221200514_migrate_attachments_to_dragonfly.rb +0 -21
  238. data/db/migrate/20130312205327_change_alchemy_users_role_to_roles.rb +0 -11
  239. data/lib/alchemy/auth_engine.rb +0 -7
  240. data/lib/alchemy/authentication_helpers.rb +0 -9
  241. data/lib/alchemy/ferret_search.rb +0 -84
  242. data/lib/extensions/array.rb +0 -25
  243. data/lib/extensions/hash.rb +0 -34
  244. data/spec/dummy/db/migrate/20130221200514_migrate_attachments_to_dragonfly.rb +0 -21
  245. data/spec/dummy/db/migrate/20130312205327_change_alchemy_users_role_to_roles.rb +0 -11
  246. data/spec/models/page_layout_spec.rb +0 -60
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require 'spec_helper'
2
3
 
3
4
  module Alchemy
@@ -7,6 +8,8 @@ module Alchemy
7
8
  File.new(File.expand_path('../../support/image.png', __FILE__))
8
9
  end
9
10
 
11
+ let(:picture) { Picture.new }
12
+
10
13
  it "is valid with valid attributes" do
11
14
  picture = Picture.new(:image_file => image_file)
12
15
  picture.should be_valid
@@ -98,6 +101,41 @@ module Alchemy
98
101
 
99
102
  end
100
103
 
104
+ describe '.filtered_by' do
105
+
106
+ let :picture do
107
+ FactoryGirl.build_stubbed(:picture)
108
+ end
109
+
110
+ context "with 'recent' as argument" do
111
+ it 'should call the .recent scope' do
112
+ Picture.should_receive(:recent).and_return(picture)
113
+ Picture.filtered_by('recent').should eq(picture)
114
+ end
115
+ end
116
+
117
+ context "with 'last_upload' as argument" do
118
+ it 'should call the .last_upload scope' do
119
+ Picture.should_receive(:last_upload).and_return(picture)
120
+ Picture.filtered_by('last_upload').should eq(picture)
121
+ end
122
+ end
123
+
124
+ context "with 'without_tag' as argument" do
125
+ it 'should call the .without_tag scope' do
126
+ Picture.should_receive(:without_tag).and_return(picture)
127
+ Picture.filtered_by('without_tag').should eq(picture)
128
+ end
129
+ end
130
+
131
+ context "with no argument" do
132
+ it 'should return the scoped collection' do
133
+ Picture.should_receive(:scoped).and_return(picture)
134
+ Picture.filtered_by('').should eq(picture)
135
+ end
136
+ end
137
+ end
138
+
101
139
  describe '.last_upload' do
102
140
 
103
141
  it "should return all pictures that have the same upload-hash as the most recent picture" do
@@ -148,5 +186,65 @@ module Alchemy
148
186
  end
149
187
  end
150
188
 
189
+ describe '#default_mask' do
190
+
191
+ before do
192
+ picture.stub!(:image_file_width).and_return(200)
193
+ picture.stub!(:image_file_height).and_return(100)
194
+ end
195
+
196
+ it "should return a Hash" do
197
+ expect(picture.default_mask('10x10')).to be_a(Hash)
198
+ end
199
+
200
+ context "cropping the picture to 200x50 pixel" do
201
+ it "should contain the correct coordination values in the hash" do
202
+ expect(picture.default_mask('200x50')).to eq({x1: 0, y1: 25, x2: 200, y2: 75})
203
+ end
204
+ end
205
+
206
+ context "if picture´s cropping size is 0x0 pixel" do
207
+ it "should not crop the picture" do
208
+ expect(picture.default_mask('0x0')).to eq({x1: 0, y1: 0, x2: 200, y2: 100})
209
+ end
210
+ end
211
+
212
+ context "cropping the picture to 50x100 pixel" do
213
+ it "should contain the correct coordination values in the hash" do
214
+ expect(picture.default_mask('50x100')).to eq({x1: 75, y1: 0, x2: 125, y2: 100})
215
+ end
216
+ end
217
+
218
+ end
219
+
220
+ describe "#cropped_thumbnail_size" do
221
+
222
+ context "if given size is blank or 111x93" do
223
+ it "should return the default size of '111x93'" do
224
+ expect(picture.cropped_thumbnail_size('')).to eq('111x93')
225
+ expect(picture.cropped_thumbnail_size('111x93')).to eq('111x93')
226
+ end
227
+ end
228
+
229
+ context "if the given width is 400 and the height is 300 because of picture cropping" do
230
+ it "should return the correct recalculated size value" do
231
+ expect(picture.cropped_thumbnail_size('400x300')).to eq('111x83')
232
+ end
233
+ end
234
+
235
+ context "if the given width is 300 and the height is 400 because of picture cropping" do
236
+ it "should return the correct recalculated size value" do
237
+ expect(picture.cropped_thumbnail_size('300x400')).to eq('70x93')
238
+ end
239
+ end
240
+ end
241
+
242
+ describe "#image_file_dimensions" do
243
+ it "should return the width and height in the format of '1024x768'" do
244
+ picture.image_file = image_file
245
+ expect(picture.image_file_dimensions).to eq('1 x 1')
246
+ end
247
+ end
248
+
151
249
  end
152
250
  end
@@ -78,12 +78,43 @@ module Alchemy
78
78
  describe '.current' do
79
79
  context 'when set to a site' do
80
80
  before { Site.current = site }
81
- specify "Language should be scoped to that site"
81
+ specify "Language should be scoped to that site" do
82
+ Language.scoped.to_sql.should match(/alchemy_languages.+site_id.+#{site.id}/)
83
+ end
82
84
  end
83
85
 
84
86
  context 'when set to nil' do
85
87
  before { Site.current = nil }
86
- specify "Language should not be scoped to a site"
88
+ specify "Language should not be scoped to a site" do
89
+ Language.scoped.to_sql.should_not match(/alchemy_languages.+site_id.+#{site.id}/)
90
+ end
91
+
92
+ it "should return default site" do
93
+ Site.current.should_not be_nil
94
+ Site.current.should == Site.default
95
+ end
96
+ end
97
+ end
98
+
99
+ describe '.layout_definitions' do
100
+ # To prevent memoization across specs
101
+ before { Site.instance_variable_set("@layout_definitions", nil) }
102
+
103
+ subject { Site.layout_definitions }
104
+
105
+ context "with file present" do
106
+ let(:definitions) { [{'name' => 'lala'}] }
107
+ before { YAML.should_receive(:load_file).and_return(definitions) }
108
+ it { should == definitions }
109
+ end
110
+
111
+ context "with empty file" do
112
+ before { YAML.should_receive(:load_file).and_return(false) }
113
+ it { should == [] }
114
+ end
115
+
116
+ context "with no file present" do
117
+ it { should == [] }
87
118
  end
88
119
  end
89
120
 
@@ -105,5 +136,32 @@ module Alchemy
105
136
  it { should be_false }
106
137
  end
107
138
  end
139
+
140
+ describe '#to_partial_path' do
141
+ let(:site) {Site.new(name: 'My custom site')}
142
+
143
+ it "returns the path to partial" do
144
+ site.to_partial_path.should == "alchemy/site_layouts/my_custom_site"
145
+ end
146
+ end
147
+
148
+ describe '#layout_partial_name' do
149
+ let(:site) {Site.new(name: 'My custom site')}
150
+
151
+ it "returns the name for layout partial" do
152
+ site.layout_partial_name.should == "my_custom_site"
153
+ end
154
+ end
155
+
156
+ describe '#layout_definition' do
157
+ let(:site) {Site.new(name: 'My custom site')}
158
+ let(:definitions) { [{'name' => 'my_custom_site', 'page_layouts' => %w(standard)}] }
159
+
160
+ it "returns layout definition from site_layouts.yml file" do
161
+ Site.stub(:layout_definitions).and_return(definitions)
162
+ site.layout_definition.should == definitions.first
163
+ end
164
+ end
165
+
108
166
  end
109
167
  end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ module Alchemy
4
+ describe Tag do
5
+
6
+ describe '.replace' do
7
+ let(:picture) { Picture.new }
8
+ let(:element) { Element.new }
9
+ let(:tag) { Tag.new(name: 'red') }
10
+ let(:new_tag) { Tag.new(name: 'green') }
11
+
12
+ before do
13
+ picture.stub!(:tag_list).and_return(['red'])
14
+ element.stub!(:tag_list).and_return(['red'])
15
+ picture.stub!(:save).and_return(true)
16
+ element.stub!(:save).and_return(true)
17
+ tag.stub!(:taggings).and_return([
18
+ mock_model(ActsAsTaggableOn::Tagging, taggable: picture),
19
+ mock_model(ActsAsTaggableOn::Tagging, taggable: element)
20
+ ])
21
+ end
22
+
23
+ it "should replace given tag with new one on all models tagged with tag" do
24
+ Tag.replace(tag, new_tag)
25
+ picture.tag_list.should eq(['green'])
26
+ element.tag_list.should eq(['green'])
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -15,8 +15,8 @@ module Alchemy
15
15
  context ".after_save" do
16
16
  let(:user) { FactoryGirl.build(:admin_user) }
17
17
 
18
- context "with send_credentials set to true" do
19
- before { user.send_credentials = true }
18
+ context "with send_credentials set to '1'" do
19
+ before { user.send_credentials = '1' }
20
20
 
21
21
  it "delivers the admin welcome mail." do
22
22
  Notifications.should_receive(:admin_user_created).and_return(OpenStruct.new(deliver: true))
@@ -186,7 +186,7 @@ module Alchemy
186
186
  describe "#pages_locked_by_me" do
187
187
  it "should return all pages that are locked by user" do
188
188
  user.save!
189
- page.lock(user)
189
+ page.lock!(user)
190
190
  user.locked_pages.should include(page)
191
191
  end
192
192
  end
@@ -194,7 +194,7 @@ module Alchemy
194
194
  describe '#unlock_pages' do
195
195
  before do
196
196
  user.save!
197
- page.lock(user)
197
+ page.lock!(user)
198
198
  end
199
199
 
200
200
  it "should unlock all users lockes pages" do
@@ -1,71 +1,62 @@
1
1
  require 'simplecov'
2
2
  require 'coveralls'
3
3
 
4
- SimpleCov.formatter = Coveralls::SimpleCov::Formatter
5
- SimpleCov.start do
6
- add_filter '/spec/'
7
- end
8
-
9
- begin
10
- require 'spork'
11
- rescue LoadError => e
4
+ if ENV['CI']
5
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
6
+ else
7
+ SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
12
8
  end
9
+ SimpleCov.start 'alchemy'
13
10
 
14
- def configure
15
- # Configure Rails Environment
16
- ENV["RAILS_ENV"] = "test"
11
+ # Configure Rails Environment
12
+ ENV["RAILS_ENV"] = "test"
17
13
 
18
- require File.expand_path("../dummy/config/environment.rb", __FILE__)
14
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
19
15
 
20
- require "rails/test_help"
21
- require "rspec/rails"
22
- require 'factory_girl'
23
- require 'factories.rb'
16
+ require "rails/test_help"
17
+ require "rspec/rails"
18
+ require 'factory_girl'
24
19
 
25
- ActionMailer::Base.delivery_method = :test
26
- ActionMailer::Base.perform_deliveries = true
27
- ActionMailer::Base.default_url_options[:host] = "test.com"
20
+ ActionMailer::Base.delivery_method = :test
21
+ ActionMailer::Base.perform_deliveries = true
22
+ ActionMailer::Base.default_url_options[:host] = "test.com"
28
23
 
29
- Rails.backtrace_cleaner.remove_silencers!
30
- # Disable rails loggin for faster IO. Remove this if you want to have a test.log
31
- Rails.logger.level = 4
24
+ Rails.backtrace_cleaner.remove_silencers!
25
+ # Disable rails loggin for faster IO. Remove this if you want to have a test.log
26
+ Rails.logger.level = 4
32
27
 
33
- # Configure capybara for integration testing
34
- require "capybara/rails"
35
- require 'capybara/poltergeist'
36
- Capybara.default_driver = :rack_test
37
- Capybara.default_selector = :css
38
- Capybara.register_driver(:rack_test_translated_header) do |app|
39
- Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_ACCEPT_LANGUAGE' => 'de' })
28
+ # Configure capybara for integration testing
29
+ require "capybara/rails"
30
+ require 'capybara/poltergeist'
31
+ Capybara.default_driver = :rack_test
32
+ Capybara.default_selector = :css
33
+ Capybara.register_driver(:rack_test_translated_header) do |app|
34
+ Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_ACCEPT_LANGUAGE' => 'de' })
35
+ end
36
+ Capybara.javascript_driver = :poltergeist
37
+
38
+ # Load support files
39
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
40
+
41
+ require 'alchemy/seeder'
42
+
43
+ RSpec.configure do |config|
44
+ config.treat_symbols_as_metadata_keys_with_true_values = true
45
+ config.run_all_when_everything_filtered = true
46
+ config.filter_run :focus
47
+ config.include Alchemy::Engine.routes.url_helpers
48
+ config.include Devise::TestHelpers, :type => :controller
49
+ config.include Alchemy::Specs::ControllerHelpers, :type => :controller
50
+ config.include Alchemy::Specs::IntegrationHelpers, :type => :feature
51
+ config.use_transactional_fixtures = true
52
+ # Make sure the database is clean and ready for test
53
+ config.before(:suite) do
54
+ truncate_all_tables
55
+ Alchemy::Seeder.seed!
40
56
  end
41
- Capybara.javascript_driver = :poltergeist
42
-
43
- # Load support files
44
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
45
-
46
- RSpec.configure do |config|
47
- require 'rspec/expectations'
48
- config.include RSpec::Matchers
49
- config.include Alchemy::Engine.routes.url_helpers
50
- config.include Devise::TestHelpers, :type => :controller
51
- config.mock_with :rspec
52
- config.use_transactional_fixtures = true
53
- # Make sure the database is clean and ready for test
54
- config.before(:suite) do
55
- truncate_all_tables
56
- Alchemy::Seeder.seed!
57
- end
58
- # Ensuring that the locale is always resetted to :en before running any tests
59
- config.before(:each) do
60
- Alchemy::Site.current = nil
61
- ::I18n.locale = :en
62
- end
57
+ # Ensuring that the locale is always resetted to :en before running any tests
58
+ config.before(:each) do
59
+ Alchemy::Site.current = nil
60
+ ::I18n.locale = :en
63
61
  end
64
-
65
- end
66
-
67
- if defined?(Spork)
68
- Spork.prefork { configure }
69
- else
70
- configure
71
62
  end
@@ -0,0 +1,35 @@
1
+ module Alchemy
2
+ module Specs
3
+
4
+ # Helpers for controller specs
5
+ #
6
+ # This file is included in rspec controller tests.
7
+ #
8
+ module ControllerHelpers
9
+
10
+ def sign_in(user=admin_user)
11
+ request.env['warden'].stub :authenticate! => user
12
+ request.env['warden'].set_user(user, store: false, run_callbacks: false)
13
+ controller.stub :current_user => user
14
+ end
15
+
16
+ def admin_user
17
+ mock_user([:admin])
18
+ end
19
+
20
+ def registered_user
21
+ mock_user([:registered])
22
+ end
23
+
24
+ def mock_user(roles)
25
+ mock_model(User,
26
+ name: 'Hermes Trismegistus',
27
+ roles: roles.map(&:to_sym),
28
+ store_request_time!: nil
29
+ )
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
@@ -5,10 +5,10 @@ module Alchemy
5
5
 
6
6
  # Helpers for integration specs
7
7
  #
8
- # This file is auto included in rspec integration/request tests.
8
+ # This file is included in rspec integration/request tests.
9
9
  #
10
- module Helpers
11
- include Authorization::TestHelper
10
+ module IntegrationHelpers
11
+ include ::Authorization::TestHelper
12
12
 
13
13
  # Shortcut method for:
14
14
  #
@@ -42,7 +42,7 @@ module Alchemy
42
42
  # For some strange reason, this isn't done automatically while running the specs
43
43
  #
44
44
  def load_authorization_rules
45
- instance = Alchemy::AuthEngine.get_instance
45
+ instance = Alchemy::Auth::Engine.get_instance
46
46
  instance.load(File.join(File.dirname(__FILE__), '../../dummy', 'config/authorization_rules.rb'))
47
47
  end
48
48
 
@@ -64,7 +64,3 @@ module Alchemy
64
64
 
65
65
  end
66
66
  end
67
-
68
- RSpec.configure do |c|
69
- c.include Alchemy::Specs::Helpers, :type => :feature
70
- end
@@ -82,6 +82,11 @@ FactoryGirl.define do
82
82
  language nil
83
83
  end
84
84
 
85
+ factory :restricted_page do
86
+ name "Restricted page"
87
+ restricted true
88
+ end
89
+
85
90
  end
86
91
 
87
92
  factory :cell, :class => 'Alchemy::Cell' do
@@ -92,10 +97,15 @@ FactoryGirl.define do
92
97
  factory :element, :class => 'Alchemy::Element' do
93
98
  name 'article'
94
99
  create_contents_after_create false
100
+
101
+ factory :unique_element do
102
+ unique true
103
+ name 'header'
104
+ end
95
105
  end
96
106
 
97
107
  factory :picture, :class => 'Alchemy::Picture' do
98
- image_file File.new(File.expand_path('../support/image.png', __FILE__))
108
+ image_file File.new(File.expand_path('../image.png', __FILE__))
99
109
  name 'image'
100
110
  image_file_name 'image.png'
101
111
  upload_hash Time.now.hash