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
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ module Alchemy
4
+ describe Admin::LayoutpagesController do
5
+
6
+ before(:each) do
7
+ sign_in(admin_user)
8
+ end
9
+
10
+ describe "#index" do
11
+ it "should assign @locked_pages" do
12
+ get :index
13
+ expect(assigns(:locked_pages)).to eq([])
14
+ end
15
+
16
+ it "should assign @layout_root" do
17
+ get :index
18
+ expect(assigns(:layout_root)).to be_a(Page)
19
+ end
20
+
21
+ it "should assign @languages" do
22
+ Language.stub!(:all).and_return([])
23
+ get :index
24
+ expect(assigns(:languages)).to eq([])
25
+ end
26
+ end
27
+ end
28
+ end
@@ -5,124 +5,53 @@ module Alchemy
5
5
  describe Admin::PagesController do
6
6
 
7
7
  before do
8
- sign_in :user, FactoryGirl.create(:admin_user)
8
+ sign_in(admin_user)
9
9
  end
10
10
 
11
11
  describe "#flush" do
12
12
 
13
13
  it "should remove the cache of all pages" do
14
- post :flush, {:format => :js}
14
+ post :flush, format: :js
15
15
  response.status.should == 200
16
16
  end
17
17
 
18
18
  end
19
19
 
20
20
  describe '#new' do
21
-
22
21
  context "pages in clipboard" do
23
22
 
24
23
  let(:clipboard) { session[:clipboard] = Clipboard.new }
25
- let(:page) { mock_model('Page', {:id => 10, :name => 'Foobar', :parent_id => 1}) }
24
+ let(:page) { mock_model('Page', name: 'Foobar') }
26
25
 
27
- before(:each) do
28
- clipboard[:pages] = [{:id => page.id, :action => 'copy'}]
26
+ before do
27
+ clipboard[:pages] = [{id: page.id, action: 'copy'}]
29
28
  end
30
29
 
31
30
  it "should load all pages from clipboard" do
32
- get :new, {:page_id => page.id, :format => :js}
31
+ get :new, {page_id: page.id, format: :js}
33
32
  assigns(:clipboard_items).should be_kind_of(Array)
34
33
  end
35
34
 
36
35
  end
37
-
38
36
  end
39
37
 
40
- describe '#order' do
41
- let(:page_1) { FactoryGirl.create(:page, visible: true) }
42
- let(:page_2) { FactoryGirl.create(:page, visible: true) }
43
- let(:page_3) { FactoryGirl.create(:page, visible: true) }
44
- let(:page_item_1) { {id: page_1.id, slug: page_1.slug, restricted: false, external: page_1.redirects_to_external?, visible: page_1.visible?, children: [page_item_2]} }
45
- let(:page_item_2) { {id: page_2.id, slug: page_2.slug, restricted: false, external: page_2.redirects_to_external?, visible: page_2.visible?, children: [page_item_3]} }
46
- let(:page_item_3) { {id: page_3.id, slug: page_3.slug, restricted: false, external: page_3.redirects_to_external?, visible: page_3.visible? } }
47
- let(:set_of_pages) { [page_item_1] }
48
-
49
- it "stores the new order" do
50
- xhr :post, :order, set: set_of_pages.to_json
51
- page_1.reload
52
- expect(page_1.descendants).to eq([page_2, page_3])
53
- end
54
-
55
- context 'with url nesting enabled' do
56
- before { Alchemy::Config.stub(get: true) }
57
-
58
- it "updates the pages urlnames" do
59
- xhr :post, :order, set: set_of_pages.to_json
60
- [page_1, page_2, page_3].map(&:reload)
61
- expect(page_1.urlname).to eq("#{page_1.slug}")
62
- expect(page_2.urlname).to eq("#{page_1.slug}/#{page_2.slug}")
63
- expect(page_3.urlname).to eq("#{page_1.slug}/#{page_2.slug}/#{page_3.slug}")
64
- end
65
-
66
- context 'with invisible page in tree' do
67
- let(:page_item_2) do
68
- {
69
- id: page_2.id,
70
- slug: page_2.slug,
71
- children: [page_item_3],
72
- visible: false
73
- }
74
- end
75
-
76
- it "does not use this pages slug in urlnames of descendants" do
77
- xhr :post, :order, set: set_of_pages.to_json
78
- [page_1, page_2, page_3].map(&:reload)
79
- expect(page_1.urlname).to eq("#{page_1.slug}")
80
- expect(page_2.urlname).to eq("#{page_1.slug}/#{page_2.slug}")
81
- expect(page_3.urlname).to eq("#{page_1.slug}/#{page_3.slug}")
82
- end
83
- end
38
+ describe '#show' do
84
39
 
85
- context 'with external page in tree' do
86
- let(:page_item_2) do
87
- {
88
- id: page_2.id,
89
- slug: page_2.slug,
90
- children: [page_item_3],
91
- external: true
92
- }
93
- end
40
+ let(:page) { mock_model('Page', language_code: 'nl') }
94
41
 
95
- it "does not use this pages slug in urlnames of descendants" do
96
- xhr :post, :order, set: set_of_pages.to_json
97
- [page_1, page_2, page_3].map(&:reload)
98
- expect(page_3.urlname).to eq("#{page_1.slug}/#{page_3.slug}")
99
- end
100
- end
101
-
102
- context 'with restricted page in tree' do
103
- let(:page_2) { FactoryGirl.create(:page, restricted: true) }
104
- let(:page_item_2) do
105
- {
106
- id: page_2.id,
107
- slug: page_2.slug,
108
- children: [page_item_3],
109
- restricted: true
110
- }
111
- end
42
+ before do
43
+ Page.stub!(:find).with("#{page.id}").and_return(page)
44
+ Page.stub!(:language_root_for).and_return(mock_model('Page'))
45
+ end
112
46
 
113
- it "updates restricted status of descendants" do
114
- xhr :post, :order, set: set_of_pages.to_json
115
- page_3.reload
116
- expect(page_3.restricted).to be_true
117
- end
118
- end
47
+ it "should assign @preview_mode with true" do
48
+ post :show, id: page.id
49
+ expect(assigns(:preview_mode)).to eq(true)
50
+ end
119
51
 
120
- it "creates legacy urls" do
121
- xhr :post, :order, set: set_of_pages.to_json
122
- [page_2, page_3].map(&:reload)
123
- expect(page_2.legacy_urls.size).to eq(1)
124
- expect(page_3.legacy_urls.size).to eq(1)
125
- end
52
+ it "should set the I18n locale to the pages language code" do
53
+ post :show, id: page.id
54
+ expect(::I18n.locale).to eq(:nl)
126
55
  end
127
56
  end
128
57
 
@@ -134,44 +63,78 @@ module Alchemy
134
63
 
135
64
  it "should always show the slug" do
136
65
  Page.stub!(:find).and_return(page)
137
- get :configure, {:id => page.id, :format => :js}
66
+ get :configure, {id: page.id, format: :js}
138
67
  response.body.should match /value="foobar"/
139
68
  end
140
69
  end
141
70
  end
142
71
 
143
72
  describe '#create' do
73
+ let(:language) { mock_model('Language', code: 'kl') }
74
+ let(:parent) { mock_model('Page', language: language) }
75
+ let(:page_params) do
76
+ {parent_id: parent.id, name: 'new Page'}
77
+ end
144
78
 
145
- let(:parent) { FactoryGirl.create(:public_page) }
146
-
147
- context "with paste_from_clipboard in parameters" do
148
- render_views
149
-
150
- let(:clipboard) { session[:clipboard] = Clipboard.new }
151
- let(:page_in_clipboard) { FactoryGirl.create(:public_page) }
79
+ context "" do
80
+ before do
81
+ Page.any_instance.stub(:set_language_from_parent_or_default_language)
82
+ Page.any_instance.stub(:save).and_return(true)
83
+ end
152
84
 
153
- before(:each) do
154
- clipboard[:pages] = [{:id => page_in_clipboard.id, :action => 'cut'}]
85
+ it "nests a new page under given parent" do
86
+ controller.stub!(:edit_admin_page_path).and_return('bla')
87
+ post :create, {page: page_params, format: :js}
88
+ expect(assigns(:page).parent_id).to eq(parent.id)
155
89
  end
156
90
 
157
- it "should create a page from clipboard" do
158
- post :create, {:paste_from_clipboard => page_in_clipboard.id, :page => {:parent_id => parent.id}, :format => :js}
159
- response.status.should == 200
160
- response.body.should match /window.location.*admin.*pages/
91
+ context "if new page can not be saved" do
92
+ it "should redirect to admin_pages_path" do
93
+ Page.any_instance.stub(:save).and_return(false)
94
+ post :create, page: {}
95
+ response.should redirect_to(admin_pages_path)
96
+ end
161
97
  end
162
98
 
99
+ context "with redirect_to in params" do
100
+ let(:page_params) do
101
+ {name: "Foobar", page_layout: 'standard', parent_id: parent.id}
102
+ end
103
+
104
+ it "should redirect to given url" do
105
+ post :create, page: page_params, redirect_to: admin_users_path
106
+ response.should redirect_to(admin_users_path)
107
+ end
108
+
109
+ context "but new page can not be saved" do
110
+ it "should redirect to admin_pages_path" do
111
+ Page.any_instance.stub(:save).and_return(false)
112
+ post :create, page: {}, redirect_to: admin_users_path
113
+ response.should redirect_to(admin_pages_path)
114
+ end
115
+ end
116
+ end
163
117
  end
164
118
 
165
- context "with redirect_to in the parameters" do
119
+ context "with paste_from_clipboard in parameters" do
120
+ let(:page_in_clipboard) { mock_model('Page') }
166
121
 
167
- let(:page_params) do
168
- {:name => "Foobar", :page_layout => 'standard', :parent_id => parent.id}
122
+ before do
123
+ Page.stub!(:find_by_id).with(parent.id).and_return(parent)
124
+ Page.stub!(:find).with(page_in_clipboard.id).and_return(page_in_clipboard)
169
125
  end
170
126
 
171
- it "should redirect to given url" do
172
- post :create, :page => page_params, :redirect_to => admin_users_path
173
- response.should redirect_to(admin_users_path)
127
+ it "should call Page#paste_from_clipboard" do
128
+ Page.should_receive(:paste_from_clipboard).with(
129
+ page_in_clipboard,
130
+ parent,
131
+ 'pasted Page'
132
+ ).and_return(
133
+ mock_model('Page', save: true, name: 'pasted Page')
134
+ )
135
+ post :create, {paste_from_clipboard: page_in_clipboard.id, page: {parent_id: parent.id, name: 'pasted Page'}, format: :js}
174
136
  end
137
+
175
138
  end
176
139
 
177
140
  end
@@ -180,17 +143,17 @@ module Alchemy
180
143
 
181
144
  let(:language) { Language.get_default }
182
145
  let(:new_language) { FactoryGirl.create(:klingonian) }
183
- let(:language_root) { FactoryGirl.create(:language_root_page, :language => language) }
146
+ let(:language_root) { FactoryGirl.create(:language_root_page, language: language) }
184
147
  let(:new_lang_root) { Page.language_root_for(new_language.id) }
185
148
 
186
149
  before(:each) do
187
- level_1 = FactoryGirl.create(:public_page, :parent_id => language_root.id, :visible => true, :name => 'Level 1')
188
- level_2 = FactoryGirl.create(:public_page, :parent_id => level_1.id, :visible => true, :name => 'Level 2')
189
- level_3 = FactoryGirl.create(:public_page, :parent_id => level_2.id, :visible => true, :name => 'Level 3')
190
- level_4 = FactoryGirl.create(:public_page, :parent_id => level_3.id, :visible => true, :name => 'Level 4')
150
+ level_1 = FactoryGirl.create(:public_page, parent_id: language_root.id, visible: true, name: 'Level 1')
151
+ level_2 = FactoryGirl.create(:public_page, parent_id: level_1.id, visible: true, name: 'Level 2')
152
+ level_3 = FactoryGirl.create(:public_page, parent_id: level_2.id, visible: true, name: 'Level 3')
153
+ level_4 = FactoryGirl.create(:public_page, parent_id: level_3.id, visible: true, name: 'Level 4')
191
154
  session[:language_code] = new_language.code
192
155
  session[:language_id] = new_language.id
193
- post :copy_language_tree, {:languages => {:new_lang_id => new_language.id, :old_lang_id => language.id}}
156
+ post :copy_language_tree, {languages: {new_lang_id: new_language.id, old_lang_id: language.id}}
194
157
  end
195
158
 
196
159
  it "should copy all pages" do
@@ -215,11 +178,11 @@ module Alchemy
215
178
  let(:page) { FactoryGirl.create(:public_page) }
216
179
 
217
180
  before do
218
- clipboard[:pages] = [{:id => page.id}]
181
+ clipboard[:pages] = [{id: page.id}]
219
182
  end
220
183
 
221
184
  it "should also remove the page from clipboard" do
222
- post :destroy, {:id => page.id, :_method => :delete}
185
+ post :destroy, {id: page.id, _method: :delete}
223
186
  clipboard[:pages].should be_empty
224
187
  end
225
188
 
@@ -240,5 +203,88 @@ module Alchemy
240
203
 
241
204
  end
242
205
 
206
+ describe '#visit' do
207
+ let(:page) { mock_model('Page', urlname: 'home') }
208
+
209
+ before do
210
+ Page.stub!(:find).with("#{page.id}").and_return(page)
211
+ page.stub!(:unlock!).and_return(true)
212
+ @controller.stub!(:multi_language?).and_return(false)
213
+ end
214
+
215
+ it "should redirect to the page path" do
216
+ expect(post :visit, id: page.id).to redirect_to(show_page_path(urlname: 'home'))
217
+ end
218
+ end
219
+
220
+ describe '#fold' do
221
+ let(:page) { mock_model('Page') }
222
+
223
+ before do
224
+ Page.stub!(:find).with(page.id).and_return(page)
225
+ end
226
+
227
+ context "if page is currently not folded" do
228
+ before do
229
+ page.stub!(:folded?).and_return(false)
230
+ end
231
+
232
+ it "should fold the page" do
233
+ page.should_receive(:fold!).with(controller.current_user.id, true).and_return(true)
234
+ post :fold, id: page.id, format: :js
235
+ end
236
+ end
237
+
238
+ context "if page is already folded" do
239
+ before do
240
+ page.stub!(:folded?).and_return(true)
241
+ end
242
+
243
+ it "should unfold the page" do
244
+ page.should_receive(:fold!).with(controller.current_user.id, false).and_return(true)
245
+ post :fold, id: page.id, format: :js
246
+ end
247
+ end
248
+ end
249
+
250
+ describe '#sort' do
251
+ before do
252
+ Page.stub!(:language_root_for).and_return(mock_model('Page'))
253
+ end
254
+
255
+ it "should assign @sorting with true" do
256
+ get :sort, format: :js
257
+ expect(assigns(:sorting)).to eq(true)
258
+ end
259
+ end
260
+
261
+ describe '#unlock' do
262
+ let(:page) { mock_model('Page', name: 'Best practices') }
263
+
264
+ before do
265
+ page.stub!(:unlock!).and_return(true)
266
+ Page.stub!(:find).with("#{page.id}").and_return(page)
267
+ Page.stub_chain(:from_current_site, :all_locked_by).and_return(nil)
268
+ end
269
+
270
+ it "should unlock the page" do
271
+ page.should_receive(:unlock!)
272
+ post :unlock, id: "#{page.id}", format: :js
273
+ end
274
+
275
+ context 'requesting for html format' do
276
+ it "should redirect to admin_pages_path" do
277
+ expect(post :unlock, id: page.id).to redirect_to(admin_pages_path)
278
+ end
279
+
280
+ context 'if passing :redirect_to through params' do
281
+ it "should redirect to the given path" do
282
+ expect(post :unlock, id: page.id, redirect_to: 'this/path').to redirect_to('this/path')
283
+ end
284
+ end
285
+ end
286
+
287
+ end
288
+
243
289
  end
244
290
  end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ module Alchemy
4
+ describe Admin::PicturesController do
5
+
6
+ before do
7
+ sign_in(admin_user)
8
+ end
9
+
10
+ describe "#index" do
11
+ it "should always paginate the records" do
12
+ Picture.should_receive(:find_paginated)
13
+ get :index
14
+ end
15
+
16
+ context "when params[:filter] is set" do
17
+ it "should filter the pictures collection by the given filter string." do
18
+ Picture.should_receive(:filtered_by).with('recent').and_return(Picture.scoped)
19
+ get :index, filter: 'recent'
20
+ end
21
+ end
22
+
23
+ context "when params[:tagged_with] is set" do
24
+ it "should filter the records by tags" do
25
+ Picture.should_receive(:tagged_with).and_return(Picture.scoped)
26
+ get :index, tagged_with: "red"
27
+ end
28
+ end
29
+
30
+ context "when params[:content_id]" do
31
+ render_views
32
+
33
+ context "is set" do
34
+ it "should render the archive_overlay partial" do
35
+ Element.stub!(:find).with('1', {:select => 'id'}).and_return(mock_model(Element))
36
+ get :index, {element_id: 1, format: :html}
37
+ expect(response).to render_template(partial: '_archive_overlay')
38
+ end
39
+ end
40
+
41
+ context "is not set" do
42
+ it "should render the default index view" do
43
+ get :index
44
+ expect(response).to render_template(:index)
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+
51
+ describe "#delete_multiple" do
52
+ let(:deletable_picture) { mock_model('Picture', name: 'pic of the pig', deletable?: true) }
53
+ let(:not_deletable_picture) { mock_model('Picture', name: 'pic of the chick', deletable?: false) }
54
+
55
+ context "no picture_ids given" do
56
+ it "should give a warning about not deleting any pictures" do
57
+ delete :delete_multiple, picture_ids: ''
58
+ expect(flash[:warn]).to match('Could not delete Pictures')
59
+ end
60
+ end
61
+
62
+ context "picture_ids given" do
63
+ context "all are deletable" do
64
+ before do
65
+ Picture.stub!(:find).and_return([deletable_picture])
66
+ end
67
+
68
+ it "should delete the pictures give a notice about deleting them" do
69
+ delete :delete_multiple, picture_ids: "#{deletable_picture.id}"
70
+ expect(flash[:notice]).to match('successfully')
71
+ end
72
+ end
73
+
74
+ context "deletable and not deletable" do
75
+ before do
76
+ Picture.stub!(:find).and_return([deletable_picture, not_deletable_picture])
77
+ end
78
+
79
+ it "should give a warning for the non deletable pictures and delete the others" do
80
+ deletable_picture.should_receive(:destroy)
81
+ delete :delete_multiple, picture_ids: "#{deletable_picture.id},#{not_deletable_picture.id}"
82
+ expect(flash[:warn]).to match('could not be deleted')
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ end
89
+ end