alchemy_cms 3.2.1 → 3.3.0.rc1

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 (556) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +28 -0
  3. data/.gitignore +2 -2
  4. data/.travis.yml +11 -3
  5. data/CHANGELOG.md +100 -0
  6. data/CONTRIBUTING.md +1 -1
  7. data/Gemfile +12 -1
  8. data/README.md +25 -7
  9. data/Rakefile +1 -3
  10. data/alchemy_cms.gemspec +7 -15
  11. data/app/assets/fonts/alchemy/icons.eot +0 -0
  12. data/app/assets/fonts/alchemy/icons.svg +28 -66
  13. data/app/assets/fonts/alchemy/icons.ttf +0 -0
  14. data/app/assets/fonts/alchemy/icons.woff +0 -0
  15. data/app/assets/images/alchemy/icons.png +0 -0
  16. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +10 -3
  17. data/app/assets/javascripts/alchemy/alchemy.buttons.js.coffee +15 -6
  18. data/app/assets/javascripts/alchemy/alchemy.char_counter.js.coffee +1 -1
  19. data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +1 -1
  20. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +10 -4
  21. data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +16 -22
  22. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +69 -32
  23. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +147 -83
  24. data/app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee +14 -14
  25. data/app/assets/javascripts/alchemy/alchemy.hotkeys.js.coffee +1 -1
  26. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +1 -1
  27. data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +55 -0
  28. data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +8 -1
  29. data/app/assets/javascripts/alchemy/alchemy.js +3 -1
  30. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +36 -31
  31. data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +35 -29
  32. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +51 -5
  33. data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +26 -10
  34. data/app/assets/javascripts/alchemy/{alchemy.windows.js.coffee → alchemy.trash_window.js.coffee} +1 -13
  35. data/app/assets/javascripts/alchemy/alchemy.uploader.js.coffee +15 -17
  36. data/app/assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js +3 -3
  37. data/app/assets/stylesheets/alchemy/_extends.scss +1 -1
  38. data/app/assets/stylesheets/alchemy/_mixins.scss +27 -0
  39. data/app/assets/stylesheets/alchemy/_variables.scss +1 -0
  40. data/app/assets/stylesheets/alchemy/admin.scss +1 -0
  41. data/app/assets/stylesheets/alchemy/archive.scss +0 -57
  42. data/app/assets/stylesheets/alchemy/base.scss +1 -18
  43. data/app/assets/stylesheets/alchemy/buttons.scss +30 -25
  44. data/app/assets/stylesheets/alchemy/dialogs.scss +25 -9
  45. data/app/assets/stylesheets/alchemy/elements.scss +182 -126
  46. data/app/assets/stylesheets/alchemy/form_fields.scss +14 -8
  47. data/app/assets/stylesheets/alchemy/forms.scss +10 -1
  48. data/app/assets/stylesheets/alchemy/frame.scss +3 -10
  49. data/app/assets/stylesheets/alchemy/icon-font.scss +13 -6
  50. data/app/assets/stylesheets/alchemy/icons.scss +16 -0
  51. data/app/assets/stylesheets/alchemy/image_library.scss +269 -0
  52. data/app/assets/stylesheets/alchemy/selects.scss +1 -0
  53. data/app/assets/stylesheets/alchemy/sitemap.scss +12 -1
  54. data/app/assets/stylesheets/alchemy/toolbar.scss +2 -2
  55. data/app/assets/stylesheets/alchemy/upload.scss +97 -87
  56. data/app/assets/stylesheets/alchemy/welcome.sass +49 -0
  57. data/app/controllers/alchemy/admin/attachments_controller.rb +21 -29
  58. data/app/controllers/alchemy/admin/base_controller.rb +23 -4
  59. data/app/controllers/alchemy/admin/clipboard_controller.rb +0 -1
  60. data/app/controllers/alchemy/admin/contents_controller.rb +2 -4
  61. data/app/controllers/alchemy/admin/dashboard_controller.rb +4 -4
  62. data/app/controllers/alchemy/admin/elements_controller.rb +20 -11
  63. data/app/controllers/alchemy/admin/essence_files_controller.rb +2 -2
  64. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +10 -9
  65. data/app/controllers/alchemy/admin/languages_controller.rb +0 -1
  66. data/app/controllers/alchemy/admin/layoutpages_controller.rb +0 -2
  67. data/app/controllers/alchemy/admin/legacy_page_urls_controller.rb +0 -1
  68. data/app/controllers/alchemy/admin/pages_controller.rb +46 -29
  69. data/app/controllers/alchemy/admin/pictures_controller.rb +44 -55
  70. data/app/controllers/alchemy/admin/resources_controller.rb +8 -75
  71. data/app/controllers/alchemy/admin/tags_controller.rb +10 -8
  72. data/app/controllers/alchemy/admin/trash_controller.rb +0 -6
  73. data/app/controllers/alchemy/api/contents_controller.rb +0 -1
  74. data/app/controllers/alchemy/api/elements_controller.rb +0 -1
  75. data/app/controllers/alchemy/api/pages_controller.rb +4 -1
  76. data/app/controllers/alchemy/attachments_controller.rb +4 -5
  77. data/app/controllers/alchemy/base_controller.rb +6 -5
  78. data/app/controllers/alchemy/elements_controller.rb +1 -1
  79. data/app/controllers/alchemy/messages_controller.rb +9 -4
  80. data/app/controllers/alchemy/pages_controller.rb +133 -137
  81. data/app/controllers/alchemy/pictures_controller.rb +12 -10
  82. data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +41 -0
  83. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +56 -0
  84. data/app/controllers/concerns/alchemy/locale_redirects.rb +38 -0
  85. data/app/controllers/concerns/alchemy/page_redirects.rb +80 -0
  86. data/app/controllers/concerns/alchemy/site_redirects.rb +22 -0
  87. data/app/helpers/alchemy/admin/attachments_helper.rb +1 -2
  88. data/app/helpers/alchemy/admin/base_helper.rb +36 -62
  89. data/app/helpers/alchemy/admin/contents_helper.rb +6 -80
  90. data/app/helpers/alchemy/admin/elements_helper.rb +36 -15
  91. data/app/helpers/alchemy/admin/essences_helper.rb +15 -8
  92. data/app/helpers/alchemy/admin/form_helper.rb +6 -10
  93. data/app/helpers/alchemy/admin/navigation_helper.rb +4 -7
  94. data/app/helpers/alchemy/admin/pages_helper.rb +14 -35
  95. data/app/helpers/alchemy/admin/pictures_helper.rb +12 -14
  96. data/app/helpers/alchemy/admin/tags_helper.rb +5 -7
  97. data/app/helpers/alchemy/base_helper.rb +9 -17
  98. data/app/helpers/alchemy/elements_block_helper.rb +5 -13
  99. data/app/helpers/alchemy/elements_helper.rb +6 -6
  100. data/app/helpers/alchemy/essences_helper.rb +3 -16
  101. data/app/helpers/alchemy/pages_helper.rb +32 -25
  102. data/app/helpers/alchemy/url_helper.rb +14 -16
  103. data/app/mailers/alchemy/messages.rb +0 -2
  104. data/app/models/alchemy.rb +0 -2
  105. data/app/models/alchemy/attachment.rb +45 -56
  106. data/app/models/alchemy/cell.rb +7 -8
  107. data/app/models/alchemy/content.rb +39 -24
  108. data/app/models/alchemy/content/factory.rb +27 -44
  109. data/app/models/alchemy/element.rb +101 -267
  110. data/app/models/alchemy/element/definitions.rb +9 -8
  111. data/app/models/alchemy/element/element_contents.rb +150 -0
  112. data/app/models/alchemy/element/element_essences.rb +109 -0
  113. data/app/models/alchemy/element/presenters.rb +18 -7
  114. data/app/models/alchemy/essence_date.rb +1 -2
  115. data/app/models/alchemy/essence_file.rb +10 -6
  116. data/app/models/alchemy/essence_html.rb +0 -1
  117. data/app/models/alchemy/essence_picture.rb +12 -4
  118. data/app/models/alchemy/essence_richtext.rb +6 -3
  119. data/app/models/alchemy/language.rb +48 -21
  120. data/app/models/alchemy/language/code.rb +1 -4
  121. data/app/models/alchemy/page.rb +33 -35
  122. data/app/models/alchemy/page/page_cells.rb +6 -10
  123. data/app/models/alchemy/page/page_elements.rb +130 -100
  124. data/app/models/alchemy/page/page_naming.rb +2 -3
  125. data/app/models/alchemy/page/page_natures.rb +50 -16
  126. data/app/models/alchemy/page/page_scopes.rb +7 -7
  127. data/app/models/alchemy/page/page_users.rb +3 -3
  128. data/app/models/alchemy/picture.rb +48 -33
  129. data/app/models/alchemy/picture/transformations.rb +8 -9
  130. data/app/models/alchemy/site.rb +19 -17
  131. data/app/models/alchemy/site/layout.rb +9 -9
  132. data/app/models/alchemy/tag.rb +0 -2
  133. data/app/models/alchemy/tree_node.rb +5 -4
  134. data/app/serializers/alchemy/attachment_serializer.rb +0 -1
  135. data/app/serializers/alchemy/base_serializer.rb +30 -0
  136. data/app/serializers/alchemy/cell_serializer.rb +0 -1
  137. data/app/serializers/alchemy/essence_boolean_serializer.rb +0 -1
  138. data/app/serializers/alchemy/essence_date_serializer.rb +0 -1
  139. data/app/serializers/alchemy/essence_file_serializer.rb +0 -1
  140. data/app/serializers/alchemy/essence_html_serializer.rb +0 -1
  141. data/app/serializers/alchemy/essence_link_serializer.rb +0 -1
  142. data/app/serializers/alchemy/essence_picture_serializer.rb +0 -1
  143. data/app/serializers/alchemy/essence_richtext_serializer.rb +0 -1
  144. data/app/serializers/alchemy/essence_select_serializer.rb +0 -1
  145. data/app/serializers/alchemy/essence_text_serializer.rb +0 -1
  146. data/app/serializers/alchemy/legacy_element_serializer.rb +0 -1
  147. data/app/serializers/alchemy/page_serializer.rb +0 -1
  148. data/app/serializers/alchemy/page_tree_serializer.rb +90 -0
  149. data/app/serializers/alchemy/picture_serializer.rb +0 -1
  150. data/app/views/alchemy/_menubar.html.erb +3 -3
  151. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +11 -16
  152. data/app/views/alchemy/admin/attachments/_attachment.html.erb +9 -9
  153. data/app/views/alchemy/admin/attachments/_files_list.html.erb +7 -15
  154. data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
  155. data/app/views/alchemy/admin/attachments/_tag_list.html.erb +2 -2
  156. data/app/views/alchemy/admin/attachments/edit.html.erb +3 -3
  157. data/app/views/alchemy/admin/attachments/index.html.erb +10 -17
  158. data/app/views/alchemy/admin/clipboard/clear.js.erb +1 -1
  159. data/app/views/alchemy/admin/clipboard/index.html.erb +3 -3
  160. data/app/views/alchemy/admin/clipboard/insert.js.erb +3 -3
  161. data/app/views/alchemy/admin/clipboard/remove.js.erb +2 -2
  162. data/app/views/alchemy/admin/contents/_missing.html.erb +5 -7
  163. data/app/views/alchemy/admin/contents/create.js.erb +1 -1
  164. data/app/views/alchemy/admin/contents/new.html.erb +2 -2
  165. data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +6 -6
  166. data/app/views/alchemy/admin/dashboard/_recent_pages.html.erb +2 -2
  167. data/app/views/alchemy/admin/dashboard/_users.html.erb +2 -2
  168. data/app/views/alchemy/admin/dashboard/help.html.erb +15 -15
  169. data/app/views/alchemy/admin/dashboard/index.html.erb +6 -6
  170. data/app/views/alchemy/admin/dashboard/info.html.erb +5 -5
  171. data/app/views/alchemy/admin/elements/_add_picture.html.erb +1 -1
  172. data/app/views/alchemy/admin/elements/_element.html.erb +52 -18
  173. data/app/views/alchemy/admin/elements/_element_footer.html.erb +11 -0
  174. data/app/views/alchemy/admin/elements/{_element_head.html.erb → _element_header.html.erb} +8 -8
  175. data/app/views/alchemy/admin/elements/_element_toolbar.html.erb +49 -0
  176. data/app/views/alchemy/admin/elements/_new_element_form.html.erb +7 -6
  177. data/app/views/alchemy/admin/elements/_picture_gallery_editor.html.erb +1 -1
  178. data/app/views/alchemy/admin/elements/_refresh_editor.js.erb +1 -1
  179. data/app/views/alchemy/admin/elements/create.js.erb +13 -8
  180. data/app/views/alchemy/admin/elements/fold.js.erb +12 -7
  181. data/app/views/alchemy/admin/elements/index.html.erb +12 -8
  182. data/app/views/alchemy/admin/elements/list.html.erb +3 -3
  183. data/app/views/alchemy/admin/elements/new.html.erb +4 -4
  184. data/app/views/alchemy/admin/elements/order.js.erb +3 -4
  185. data/app/views/alchemy/admin/elements/publish.js.erb +15 -0
  186. data/app/views/alchemy/admin/elements/trash.js.erb +3 -3
  187. data/app/views/alchemy/admin/elements/update.js.erb +7 -8
  188. data/app/views/alchemy/admin/essence_files/edit.html.erb +16 -13
  189. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +3 -3
  190. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +8 -8
  191. data/app/views/alchemy/admin/languages/_form.html.erb +12 -3
  192. data/app/views/alchemy/admin/languages/_language.html.erb +8 -2
  193. data/app/views/alchemy/admin/languages/_table.html.erb +11 -5
  194. data/app/views/alchemy/admin/languages/index.html.erb +1 -1
  195. data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +8 -8
  196. data/app/views/alchemy/admin/layoutpages/edit.html.erb +2 -2
  197. data/app/views/alchemy/admin/layoutpages/index.html.erb +6 -13
  198. data/app/views/alchemy/admin/leave.html.erb +5 -5
  199. data/app/views/alchemy/admin/legacy_page_urls/_form.html.erb +1 -1
  200. data/app/views/alchemy/admin/legacy_page_urls/_legacy_page_url.html.erb +4 -4
  201. data/app/views/alchemy/admin/legacy_page_urls/_new.html.erb +1 -1
  202. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +9 -9
  203. data/app/views/alchemy/admin/pages/_external_link.html.erb +6 -6
  204. data/app/views/alchemy/admin/pages/_file_link.html.erb +6 -6
  205. data/app/views/alchemy/admin/pages/_form.html.erb +6 -6
  206. data/app/views/alchemy/admin/pages/_internal_link.html.erb +9 -11
  207. data/app/views/alchemy/admin/pages/_legacy_urls.html.erb +3 -3
  208. data/app/views/alchemy/admin/pages/_locked_page.html.erb +4 -4
  209. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +2 -2
  210. data/app/views/alchemy/admin/pages/_page.html.erb +95 -80
  211. data/app/views/alchemy/admin/pages/_page_for_links.html.erb +22 -22
  212. data/app/views/alchemy/admin/pages/_page_infos.html.erb +12 -0
  213. data/app/views/alchemy/admin/pages/_page_status.html.erb +7 -9
  214. data/app/views/alchemy/admin/pages/_sitemap.html.erb +35 -6
  215. data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +0 -3
  216. data/app/views/alchemy/admin/pages/configure.html.erb +1 -1
  217. data/app/views/alchemy/admin/pages/configure_external.html.erb +4 -4
  218. data/app/views/alchemy/admin/pages/edit.html.erb +39 -44
  219. data/app/views/alchemy/admin/pages/flush.js.erb +1 -1
  220. data/app/views/alchemy/admin/pages/fold.js.erb +2 -3
  221. data/app/views/alchemy/admin/pages/index.html.erb +15 -22
  222. data/app/views/alchemy/admin/pages/info.html.erb +8 -8
  223. data/app/views/alchemy/admin/pages/link.html.erb +3 -3
  224. data/app/views/alchemy/admin/pages/locked.html.erb +1 -1
  225. data/app/views/alchemy/admin/pages/new.html.erb +4 -4
  226. data/app/views/alchemy/admin/pages/sort.js.erb +1 -2
  227. data/app/views/alchemy/admin/pages/unlock.js.erb +1 -1
  228. data/app/views/alchemy/admin/pages/update.js.erb +3 -3
  229. data/app/views/alchemy/admin/partials/_autocomplete_tag_list.html.erb +1 -1
  230. data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +1 -1
  231. data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +1 -1
  232. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +9 -15
  233. data/app/views/alchemy/admin/partials/_search_form.html.erb +14 -13
  234. data/app/views/alchemy/admin/partials/_sub_navigation.html.erb +1 -1
  235. data/app/views/alchemy/admin/pictures/_archive.html.erb +14 -14
  236. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +30 -36
  237. data/app/views/alchemy/admin/pictures/_filter_bar.html.erb +5 -5
  238. data/app/views/alchemy/admin/pictures/{edit.html.erb → _form.html.erb} +7 -6
  239. data/app/views/alchemy/admin/pictures/_infos.html.erb +50 -0
  240. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
  241. data/app/views/alchemy/admin/pictures/_picture.html.erb +17 -51
  242. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -1
  243. data/app/views/alchemy/admin/pictures/_tag_list.html.erb +2 -2
  244. data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +6 -6
  245. data/app/views/alchemy/admin/pictures/index.html.erb +28 -36
  246. data/app/views/alchemy/admin/pictures/show.html.erb +46 -9
  247. data/app/views/alchemy/admin/pictures/update.js.erb +6 -0
  248. data/app/views/alchemy/admin/resources/_form.html.erb +3 -3
  249. data/app/views/alchemy/admin/resources/_resource.html.erb +4 -4
  250. data/app/views/alchemy/admin/resources/_table.html.erb +5 -6
  251. data/app/views/alchemy/admin/resources/index.csv.erb +12 -10
  252. data/app/views/alchemy/admin/resources/index.html.erb +4 -4
  253. data/app/views/alchemy/admin/sites/index.html.erb +1 -1
  254. data/app/views/alchemy/admin/tags/_tag.html.erb +4 -4
  255. data/app/views/alchemy/admin/tags/edit.html.erb +5 -5
  256. data/app/views/alchemy/admin/tags/index.html.erb +8 -8
  257. data/app/views/alchemy/admin/tags/new.html.erb +2 -2
  258. data/app/views/alchemy/admin/trash/clear.js.erb +1 -1
  259. data/app/views/alchemy/admin/trash/index.html.erb +8 -6
  260. data/app/views/alchemy/admin/uploader/_button.html.erb +39 -0
  261. data/app/views/alchemy/admin/uploader/_setup.html.erb +13 -0
  262. data/app/views/alchemy/base/500.html.erb +4 -4
  263. data/app/views/alchemy/elements/_editor_not_found.html.erb +1 -1
  264. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +3 -4
  265. data/app/views/alchemy/essences/_essence_boolean_view.html.erb +1 -1
  266. data/app/views/alchemy/essences/_essence_date_editor.html.erb +2 -6
  267. data/app/views/alchemy/essences/_essence_date_view.html.erb +1 -1
  268. data/app/views/alchemy/essences/_essence_file_editor.html.erb +9 -11
  269. data/app/views/alchemy/essences/_essence_file_view.html.erb +11 -5
  270. data/app/views/alchemy/essences/_essence_html_editor.html.erb +1 -1
  271. data/app/views/alchemy/essences/_essence_link_editor.html.erb +1 -1
  272. data/app/views/alchemy/essences/_essence_link_view.html.erb +1 -1
  273. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +47 -52
  274. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +1 -1
  275. data/app/views/alchemy/essences/_essence_richtext_view.html.erb +1 -1
  276. data/app/views/alchemy/essences/_essence_select_editor.html.erb +23 -13
  277. data/app/views/alchemy/essences/_essence_text_editor.html.erb +1 -1
  278. data/app/views/alchemy/essences/_essence_text_view.html.erb +1 -1
  279. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +29 -36
  280. data/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb +5 -5
  281. data/app/views/alchemy/language_links/_language.html.erb +15 -9
  282. data/app/views/alchemy/messages/contact_form_mail.de.text.erb +1 -1
  283. data/app/views/alchemy/messages/contact_form_mail.en.text.erb +1 -1
  284. data/app/views/alchemy/messages/contact_form_mail.es.text.erb +1 -1
  285. data/app/views/alchemy/navigation/_link.html.erb +0 -1
  286. data/app/views/alchemy/pages/show.rss.builder +6 -4
  287. data/app/views/alchemy/welcome.html.erb +28 -0
  288. data/app/views/layouts/alchemy/admin.html.erb +14 -10
  289. data/bin/alchemy +3 -4
  290. data/bin/rspec +7 -0
  291. data/bin/spring +15 -0
  292. data/config/alchemy/config.yml +16 -17
  293. data/config/initializers/assets.rb +13 -0
  294. data/config/locales/alchemy.de.yml +27 -29
  295. data/config/locales/alchemy.en.yml +23 -29
  296. data/config/locales/alchemy.es.yml +23 -29
  297. data/config/locales/alchemy.fr.yml +19 -28
  298. data/config/locales/alchemy.nl.yml +19 -27
  299. data/config/locales/alchemy.ru.yml +19 -28
  300. data/config/routes.rb +53 -54
  301. data/config/spring.rb +2 -0
  302. data/db/migrate/20130827094554_alchemy_two_point_six.rb +1 -3
  303. data/db/migrate/20150608204610_add_parent_element_id_to_alchemy_elements.rb +6 -0
  304. data/db/migrate/20150729151825_add_link_text_to_alchemy_essence_files.rb +5 -0
  305. data/db/migrate/20150906195818_add_locale_to_alchemy_languages.rb +7 -0
  306. data/lib/alchemy/auth_accessors.rb +1 -1
  307. data/lib/alchemy/cache_digests/template_tracker.rb +7 -13
  308. data/lib/alchemy/config.rb +5 -7
  309. data/lib/alchemy/configuration_methods.rb +11 -1
  310. data/lib/alchemy/controller_actions.rb +9 -12
  311. data/lib/alchemy/engine.rb +11 -28
  312. data/lib/alchemy/errors.rb +0 -1
  313. data/lib/alchemy/essence.rb +20 -20
  314. data/lib/alchemy/filetypes.rb +1 -3
  315. data/lib/alchemy/forms/builder.rb +0 -2
  316. data/lib/alchemy/hints.rb +1 -3
  317. data/lib/alchemy/i18n.rb +81 -53
  318. data/lib/alchemy/kaminari/scoped_pagination_url_helper.rb +0 -2
  319. data/lib/alchemy/locale.rb +0 -1
  320. data/lib/alchemy/logger.rb +1 -3
  321. data/lib/alchemy/modules.rb +3 -3
  322. data/lib/alchemy/mount_point.rb +0 -2
  323. data/lib/alchemy/name_conversions.rb +1 -3
  324. data/lib/alchemy/on_page_layout.rb +37 -23
  325. data/lib/alchemy/on_page_layout/callbacks_runner.rb +34 -0
  326. data/lib/alchemy/page_layout.rb +23 -24
  327. data/lib/alchemy/paths.rb +32 -0
  328. data/lib/alchemy/permissions.rb +20 -20
  329. data/lib/alchemy/picture_attributes.rb +0 -3
  330. data/lib/alchemy/resource.rb +66 -22
  331. data/lib/alchemy/resources_helper.rb +48 -11
  332. data/lib/alchemy/routing_constraints.rb +4 -5
  333. data/lib/alchemy/seeder.rb +1 -4
  334. data/lib/alchemy/shell.rb +12 -14
  335. data/lib/alchemy/tasks/helpers.rb +5 -7
  336. data/lib/alchemy/test_support/essence_shared_examples.rb +24 -24
  337. data/lib/alchemy/test_support/factories.rb +2 -146
  338. data/lib/alchemy/test_support/factories/attachment_factory.rb +9 -0
  339. data/lib/alchemy/test_support/factories/cell_factory.rb +9 -0
  340. data/lib/alchemy/test_support/factories/content_factory.rb +10 -0
  341. data/lib/alchemy/test_support/factories/dummy_user_factory.rb +21 -0
  342. data/lib/alchemy/test_support/factories/element_factory.rb +21 -0
  343. data/lib/alchemy/test_support/factories/essence_file_factory.rb +8 -0
  344. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +8 -0
  345. data/lib/alchemy/test_support/factories/essence_text_factory.rb +7 -0
  346. data/lib/alchemy/test_support/factories/language_factory.rb +28 -0
  347. data/lib/alchemy/test_support/factories/page_factory.rb +45 -0
  348. data/lib/alchemy/test_support/factories/picture_factory.rb +10 -0
  349. data/lib/alchemy/test_support/factories/site_factory.rb +12 -0
  350. data/lib/alchemy/test_support/integration_helpers.rb +0 -3
  351. data/lib/alchemy/tinymce.rb +24 -35
  352. data/lib/alchemy/touching.rb +5 -6
  353. data/lib/alchemy/upgrader.rb +3 -5
  354. data/lib/alchemy/upgrader/tasks/available_contents_upgrader.rb +155 -0
  355. data/lib/alchemy/upgrader/tasks/nestable_elements_migration.rb +71 -0
  356. data/lib/alchemy/upgrader/tasks/three_point_two_task.rb +31 -0
  357. data/lib/alchemy/upgrader/three_point_three.rb +50 -0
  358. data/lib/alchemy/upgrader/three_point_two.rb +3 -32
  359. data/lib/alchemy/upgrader/three_point_zero.rb +0 -1
  360. data/lib/alchemy/version.rb +1 -1
  361. data/lib/rails/generators/alchemy/base.rb +1 -1
  362. data/lib/rails/generators/alchemy/elements/elements_generator.rb +1 -7
  363. data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +5 -7
  364. data/lib/rails/generators/alchemy/elements/templates/editor.html.haml +6 -8
  365. data/lib/rails/generators/alchemy/elements/templates/editor.html.slim +6 -7
  366. data/lib/rails/generators/alchemy/elements/templates/view.html.erb +4 -4
  367. data/lib/rails/generators/alchemy/elements/templates/view.html.haml +3 -3
  368. data/lib/rails/generators/alchemy/elements/templates/view.html.slim +3 -3
  369. data/lib/rails/generators/alchemy/essence/essence_generator.rb +2 -3
  370. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +1 -1
  371. data/lib/rails/generators/alchemy/install/files/alchemy.de.yml +2 -2
  372. data/lib/rails/generators/alchemy/install/files/alchemy.en.yml +2 -2
  373. data/lib/rails/generators/alchemy/install/files/alchemy.es.yml +3 -3
  374. data/lib/rails/generators/alchemy/install/install_generator.rb +0 -1
  375. data/lib/rails/generators/alchemy/install/templates/elements.yml.tt +2 -2
  376. data/lib/rails/generators/alchemy/install/templates/page_layouts.yml.tt +1 -1
  377. data/lib/rails/generators/alchemy/module/module_generator.rb +1 -1
  378. data/lib/rails/templates/alchemy.rb +2 -2
  379. data/lib/tasks/alchemy/convert.rake +4 -8
  380. data/lib/tasks/alchemy/db.rake +2 -3
  381. data/lib/tasks/alchemy/install.rake +3 -4
  382. data/lib/tasks/alchemy/tidy.rake +4 -5
  383. data/lib/tasks/alchemy/upgrade.rake +2 -4
  384. data/spec/controllers/{admin → alchemy/admin}/attachments_controller_spec.rb +26 -44
  385. data/spec/controllers/{admin → alchemy/admin}/base_controller_spec.rb +14 -1
  386. data/spec/controllers/{admin → alchemy/admin}/clipboard_controller_spec.rb +3 -3
  387. data/spec/controllers/{admin → alchemy/admin}/contents_controller_spec.rb +4 -4
  388. data/spec/controllers/{admin → alchemy/admin}/dashboard_controller_spec.rb +11 -6
  389. data/spec/controllers/{admin → alchemy/admin}/elements_controller_spec.rb +54 -31
  390. data/spec/controllers/{admin → alchemy/admin}/essence_files_controller_spec.rb +8 -3
  391. data/spec/controllers/{admin → alchemy/admin}/essence_pictures_controller_spec.rb +3 -3
  392. data/spec/controllers/{admin → alchemy/admin}/languages_controller_spec.rb +13 -1
  393. data/spec/controllers/{admin → alchemy/admin}/layoutpages_controller_spec.rb +0 -6
  394. data/spec/controllers/{admin → alchemy/admin}/pages_controller_spec.rb +103 -35
  395. data/spec/controllers/{admin → alchemy/admin}/pictures_controller_spec.rb +133 -108
  396. data/spec/controllers/alchemy/admin/resources_controller_spec.rb +81 -0
  397. data/spec/controllers/{admin → alchemy/admin}/trash_controller_spec.rb +12 -13
  398. data/spec/controllers/alchemy/api/contents_controller_spec.rb +12 -13
  399. data/spec/controllers/alchemy/api/elements_controller_spec.rb +8 -9
  400. data/spec/controllers/alchemy/api/pages_controller_spec.rb +40 -7
  401. data/spec/controllers/{attachments_controller_spec.rb → alchemy/attachments_controller_spec.rb} +7 -7
  402. data/spec/controllers/alchemy/base_controller_spec.rb +106 -0
  403. data/spec/controllers/{elements_controller_spec.rb → alchemy/elements_controller_spec.rb} +4 -4
  404. data/spec/controllers/{messages_controller_spec.rb → alchemy/messages_controller_spec.rb} +14 -9
  405. data/spec/controllers/alchemy/on_page_layout_mixin_spec.rb +330 -0
  406. data/spec/controllers/{pages_controller_spec.rb → alchemy/pages_controller_spec.rb} +167 -89
  407. data/spec/controllers/{pictures_controller_spec.rb → alchemy/pictures_controller_spec.rb} +42 -20
  408. data/spec/dummy/app/models/dummy_user.rb +4 -0
  409. data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_view.html.erb +31 -0
  410. data/spec/dummy/app/views/alchemy/elements/_article_editor.html.erb +6 -10
  411. data/spec/dummy/app/views/alchemy/elements/_article_view.html.erb +9 -24
  412. data/spec/dummy/app/views/alchemy/elements/_bild_editor.html.erb +3 -0
  413. data/spec/dummy/app/views/alchemy/elements/_bild_view.html.erb +5 -0
  414. data/spec/dummy/app/views/alchemy/elements/_contactform_editor.html.erb +6 -0
  415. data/spec/dummy/app/views/alchemy/elements/_contactform_view.html.erb +16 -0
  416. data/spec/dummy/app/views/alchemy/elements/_download_editor.html.erb +3 -0
  417. data/spec/dummy/app/views/alchemy/elements/_download_view.html.erb +5 -0
  418. data/spec/dummy/app/views/alchemy/elements/_erb_element_editor.html.erb +3 -0
  419. data/spec/dummy/app/views/alchemy/elements/_erb_element_view.html.erb +5 -0
  420. data/spec/dummy/app/views/alchemy/elements/_header_editor.html.erb +3 -0
  421. data/spec/dummy/app/views/alchemy/elements/_header_view.html.erb +5 -0
  422. data/spec/dummy/app/views/alchemy/elements/_news_editor.html.erb +5 -0
  423. data/spec/dummy/app/views/alchemy/elements/_search_editor.html.erb +1 -0
  424. data/spec/dummy/app/views/alchemy/elements/_search_view.html.erb +4 -0
  425. data/spec/dummy/app/views/alchemy/elements/_slide_editor.html.erb +3 -0
  426. data/spec/dummy/app/views/alchemy/elements/_slide_view.html.erb +5 -0
  427. data/spec/dummy/app/views/alchemy/elements/_slider_editor.html.erb +2 -0
  428. data/spec/dummy/app/views/alchemy/elements/_slider_view.html.erb +4 -0
  429. data/spec/dummy/app/views/alchemy/elements/_text_editor.html.erb +3 -0
  430. data/spec/dummy/app/views/alchemy/elements/_text_view.html.erb +5 -0
  431. data/spec/dummy/app/views/alchemy/page_layouts/_standard.html.erb +1 -0
  432. data/spec/dummy/config/alchemy/elements.yml +10 -13
  433. data/spec/dummy/config/alchemy/page_layouts.yml +1 -1
  434. data/spec/dummy/config/initializers/alchemy.rb +1 -0
  435. data/spec/dummy/config/locales/kl.yml +2 -0
  436. data/spec/dummy/db/migrate/20150608204610_add_parent_element_id_to_alchemy_elements.rb +1 -0
  437. data/spec/dummy/db/migrate/20150729151825_add_link_text_to_alchemy_essence_files.rb +1 -0
  438. data/spec/dummy/db/migrate/20150906195818_add_locale_to_alchemy_languages.rb +1 -0
  439. data/spec/dummy/db/schema.rb +10 -6
  440. data/spec/factories.rb +13 -0
  441. data/spec/features/admin/admin_layout_spec.rb +14 -0
  442. data/spec/features/admin/dashboard_spec.rb +1 -2
  443. data/spec/features/admin/edit_elements_feature_spec.rb +36 -0
  444. data/spec/features/admin/language_tree_feature_spec.rb +7 -8
  445. data/spec/features/admin/languages_features_spec.rb +65 -0
  446. data/spec/features/admin/legacy_page_url_management_spec.rb +3 -3
  447. data/spec/features/admin/link_overlay_spec.rb +16 -17
  448. data/spec/features/admin/locale_select_feature_spec.rb +1 -1
  449. data/spec/features/admin/modules_integration_spec.rb +0 -1
  450. data/spec/features/admin/navigation_feature_spec.rb +11 -2
  451. data/spec/features/admin/page_creation_feature_spec.rb +5 -5
  452. data/spec/features/admin/page_editing_feature_spec.rb +6 -6
  453. data/spec/features/admin/picture_library_integration_spec.rb +3 -3
  454. data/spec/features/admin/resources_integration_spec.rb +7 -12
  455. data/spec/features/admin/site_select_feature_spec.rb +1 -2
  456. data/spec/features/admin/tinymce_feature_spec.rb +0 -1
  457. data/spec/features/page_feature_spec.rb +57 -158
  458. data/spec/features/page_redirects_spec.rb +358 -0
  459. data/spec/features/picture_security_spec.rb +1 -7
  460. data/spec/fixtures/animated.gif +0 -0
  461. data/spec/helpers/{admin → alchemy/admin}/attachments_helper_spec.rb +0 -0
  462. data/spec/helpers/{admin → alchemy/admin}/base_helper_spec.rb +39 -29
  463. data/spec/helpers/{admin → alchemy/admin}/contents_helper_spec.rb +4 -23
  464. data/spec/helpers/{admin → alchemy/admin}/elements_helper_spec.rb +141 -5
  465. data/spec/helpers/{admin → alchemy/admin}/essences_helper_spec.rb +69 -8
  466. data/spec/helpers/{admin → alchemy/admin}/navigation_helper_spec.rb +43 -37
  467. data/spec/helpers/{admin → alchemy/admin}/pages_helper_spec.rb +6 -38
  468. data/spec/helpers/{admin → alchemy/admin}/pictures_helper_spec.rb +0 -1
  469. data/spec/helpers/{admin → alchemy/admin}/tags_helper_spec.rb +1 -3
  470. data/spec/helpers/{base_helper_spec.rb → alchemy/base_helper_spec.rb} +1 -2
  471. data/spec/helpers/{elements_block_helper_spec.rb → alchemy/elements_block_helper_spec.rb} +3 -3
  472. data/spec/helpers/{elements_helper_spec.rb → alchemy/elements_helper_spec.rb} +18 -19
  473. data/spec/helpers/alchemy/essences_helper_spec.rb +85 -0
  474. data/spec/helpers/{pages_helper_spec.rb → alchemy/pages_helper_spec.rb} +125 -39
  475. data/spec/helpers/alchemy/picture_url_helpers_spec.rb +78 -0
  476. data/spec/helpers/{url_helper_spec.rb → alchemy/url_helper_spec.rb} +66 -40
  477. data/spec/libraries/config_spec.rb +2 -3
  478. data/spec/libraries/controller_actions_spec.rb +18 -18
  479. data/spec/libraries/i18n_spec.rb +7 -0
  480. data/spec/libraries/page_layout_spec.rb +13 -7
  481. data/spec/libraries/paths_spec.rb +15 -0
  482. data/spec/libraries/permissions_spec.rb +6 -7
  483. data/spec/libraries/resource_spec.rb +48 -75
  484. data/spec/libraries/resources_helper_spec.rb +55 -6
  485. data/spec/libraries/shell_spec.rb +0 -4
  486. data/spec/libraries/template_tracker_spec.rb +4 -13
  487. data/spec/libraries/tinymce_spec.rb +53 -9
  488. data/spec/mailers/{messages_spec.rb → alchemy/messages_spec.rb} +0 -2
  489. data/spec/models/{attachment_spec.rb → alchemy/attachment_spec.rb} +43 -20
  490. data/spec/models/{cell_spec.rb → alchemy/cell_spec.rb} +2 -3
  491. data/spec/models/{content_spec.rb → alchemy/content_spec.rb} +179 -70
  492. data/spec/models/{element_spec.rb → alchemy/element_spec.rb} +315 -70
  493. data/spec/models/{element_to_page_spec.rb → alchemy/element_to_page_spec.rb} +0 -1
  494. data/spec/models/{essence_boolean_spec.rb → alchemy/essence_boolean_spec.rb} +0 -0
  495. data/spec/models/{essence_date_spec.rb → alchemy/essence_date_spec.rb} +2 -3
  496. data/spec/models/{essence_file_spec.rb → alchemy/essence_file_spec.rb} +2 -5
  497. data/spec/models/{essence_html_spec.rb → alchemy/essence_html_spec.rb} +1 -1
  498. data/spec/models/{essence_link_spec.rb → alchemy/essence_link_spec.rb} +0 -0
  499. data/spec/models/{essence_picture_spec.rb → alchemy/essence_picture_spec.rb} +101 -29
  500. data/spec/models/{essence_richtext_spec.rb → alchemy/essence_richtext_spec.rb} +7 -2
  501. data/spec/models/{essence_select_spec.rb → alchemy/essence_select_spec.rb} +0 -0
  502. data/spec/models/{essence_text_spec.rb → alchemy/essence_text_spec.rb} +4 -8
  503. data/spec/models/alchemy/language_spec.rb +243 -0
  504. data/spec/models/{legacy_page_url_spec.rb → alchemy/legacy_page_url_spec.rb} +1 -1
  505. data/spec/models/{message_spec.rb → alchemy/message_spec.rb} +0 -0
  506. data/spec/models/{page_spec.rb → alchemy/page_spec.rb} +460 -248
  507. data/spec/models/{picture_spec.rb → alchemy/picture_spec.rb} +118 -30
  508. data/spec/models/{site_spec.rb → alchemy/site_spec.rb} +19 -84
  509. data/spec/models/{tag_spec.rb → alchemy/tag_spec.rb} +1 -3
  510. data/spec/models/dummy_model_spec.rb +1 -2
  511. data/spec/requests/alchemy/admin/resources_requests_spec.rb +26 -0
  512. data/spec/requests/alchemy/admin/site_requests_spec.rb +19 -0
  513. data/spec/requests/alchemy/site_requests_spec.rb +18 -0
  514. data/spec/requests/alchemy/sitemap_spec.rb +56 -0
  515. data/spec/routing/api_routing_spec.rb +1 -1
  516. data/spec/routing/routing_spec.rb +121 -15
  517. data/spec/spec_helper.rb +2 -1
  518. data/spec/support/hint_examples.rb +1 -3
  519. data/spec/support/test_tweaks.rb +3 -3
  520. data/spec/support/transformation_examples.rb +6 -7
  521. data/spec/tasks/helpers_spec.rb +2 -4
  522. data/spec/views/admin/pictures/show_spec.rb +43 -0
  523. data/spec/views/essences/essence_boolean_editor_spec.rb +0 -1
  524. data/spec/views/essences/essence_boolean_view_spec.rb +2 -4
  525. data/spec/views/essences/essence_date_view_spec.rb +0 -1
  526. data/spec/views/essences/essence_file_editor_spec.rb +4 -6
  527. data/spec/views/essences/essence_file_view_spec.rb +56 -3
  528. data/spec/views/essences/essence_link_view_spec.rb +1 -1
  529. data/spec/views/essences/essence_picture_editor_spec.rb +80 -0
  530. data/spec/views/essences/essence_picture_view_spec.rb +0 -1
  531. data/spec/views/essences/essence_select_view_spec.rb +0 -1
  532. data/spec/views/essences/essence_text_view_spec.rb +0 -1
  533. data/vendor/assets/javascripts/handlebars.js +4608 -0
  534. data/vendor/assets/javascripts/tinymce/langs/de.js +19 -0
  535. data/vendor/assets/javascripts/tinymce/langs/es.js +19 -0
  536. data/vendor/assets/javascripts/tinymce/langs/fr.js +23 -4
  537. data/vendor/assets/javascripts/tinymce/langs/nl.js +22 -3
  538. data/vendor/assets/javascripts/tinymce/langs/ru.js +22 -3
  539. data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.min.js +1 -1
  540. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.min.js +1 -1
  541. data/vendor/assets/javascripts/tinymce/themes/modern/theme.min.js +1 -1
  542. data/vendor/assets/javascripts/tinymce/tinymce.min.js +12 -13
  543. metadata +274 -256
  544. data/app/views/alchemy/admin/attachments/create.js.erb +0 -11
  545. data/app/views/alchemy/admin/attachments/new.html.erb +0 -14
  546. data/app/views/alchemy/admin/elements/_element_foot.html.erb +0 -36
  547. data/app/views/alchemy/admin/partials/_upload_form.html.erb +0 -67
  548. data/app/views/alchemy/admin/pictures/info.html.erb +0 -38
  549. data/app/views/alchemy/admin/pictures/new.html.erb +0 -16
  550. data/lib/alchemy/middleware/rescue_old_cookies.rb +0 -27
  551. data/spec/controllers/admin/resources_controller_spec.rb +0 -53
  552. data/spec/controllers/base_controller_spec.rb +0 -51
  553. data/spec/helpers/essences_helper_spec.rb +0 -156
  554. data/spec/helpers/picture_url_helpers_spec.rb +0 -35
  555. data/spec/libraries/on_page_layout_spec.rb +0 -112
  556. data/spec/models/language_spec.rb +0 -123
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Alchemy::LegacyPageUrl do
4
- let(:page) { build_stubbed(:page) }
4
+ let(:page) { build_stubbed(:alchemy_page) }
5
5
 
6
6
  let(:page_url_with_parameters) do
7
7
  Alchemy::LegacyPageUrl.new(urlname: 'index.php?id=2', page: page)
@@ -4,23 +4,21 @@ require 'spec_helper'
4
4
 
5
5
  module Alchemy
6
6
  describe Page do
7
-
8
7
  let(:rootpage) { Page.root }
9
8
  let(:language) { Language.default }
10
- let(:klingonian) { FactoryGirl.create(:klingonian) }
11
- let(:language_root) { FactoryGirl.create(:language_root_page) }
9
+ let(:klingon) { create(:alchemy_language, :klingon) }
10
+ let(:language_root) { create(:alchemy_page, :language_root) }
12
11
  let(:page) { mock_model(Page, page_layout: 'foo') }
13
- let(:public_page) { FactoryGirl.create(:public_page) }
14
- let(:news_page) { FactoryGirl.create(:public_page, page_layout: 'news', do_not_autogenerate: false) }
15
-
12
+ let(:public_page) { create(:alchemy_page, :public) }
13
+ let(:news_page) { create(:alchemy_page, :public, page_layout: 'news', do_not_autogenerate: false) }
16
14
 
17
15
  # Validations
18
16
 
19
17
  context 'validations' do
20
18
  context "Creating a normal content page" do
21
- let(:contentpage) { FactoryGirl.build(:page) }
22
- let(:with_same_urlname) { FactoryGirl.create(:page, urlname: "existing_twice") }
23
- let(:global_with_same_urlname) { FactoryGirl.create(:page, urlname: "existing_twice", layoutpage: true) }
19
+ let(:contentpage) { build(:alchemy_page) }
20
+ let(:with_same_urlname) { create(:alchemy_page, urlname: "existing_twice") }
21
+ let(:global_with_same_urlname) { create(:alchemy_page, urlname: "existing_twice", layoutpage: true) }
24
22
 
25
23
  context "when its urlname exists as global page" do
26
24
  before { global_with_same_urlname }
@@ -55,7 +53,7 @@ module Alchemy
55
53
  end
56
54
 
57
55
  context "with url_nesting set to true" do
58
- let(:other_parent) { create(:page, parent_id: Page.root.id, visible: true) }
56
+ let(:other_parent) { create(:alchemy_page, parent_id: Page.root.id, visible: true) }
59
57
 
60
58
  before do
61
59
  allow(Config).to receive(:get).and_return(true)
@@ -76,7 +74,7 @@ module Alchemy
76
74
  end
77
75
 
78
76
  context "creating the rootpage without parent_id and page_layout" do
79
- let(:rootpage) { build(:page, parent_id: nil, page_layout: nil, name: 'Rootpage') }
77
+ let(:rootpage) { build(:alchemy_page, parent_id: nil, page_layout: nil, name: 'Rootpage') }
80
78
 
81
79
  before do
82
80
  Page.delete_all
@@ -88,7 +86,7 @@ module Alchemy
88
86
  end
89
87
 
90
88
  context "saving a systempage" do
91
- let(:systempage) { build(:systempage) }
89
+ let(:systempage) { build(:alchemy_page, :system) }
92
90
 
93
91
  it "should not validate the page_layout" do
94
92
  expect(systempage).to be_valid
@@ -96,7 +94,7 @@ module Alchemy
96
94
  end
97
95
 
98
96
  context 'saving an external page' do
99
- let(:external_page) { build(:page, page_layout: 'external') }
97
+ let(:external_page) { build(:alchemy_page, page_layout: 'external') }
100
98
 
101
99
  it "does not pass with invalid url given" do
102
100
  external_page.urlname = 'not, a valid page url'
@@ -126,12 +124,11 @@ module Alchemy
126
124
  end
127
125
  end
128
126
 
129
-
130
127
  # Callbacks
131
128
 
132
129
  context 'callbacks' do
133
130
  let(:page) do
134
- FactoryGirl.create(:page, name: 'My Testpage', language: language, parent_id: language_root.id)
131
+ create(:alchemy_page, name: 'My Testpage', language: language, parent_id: language_root.id)
135
132
  end
136
133
 
137
134
  context 'before_save' do
@@ -187,7 +184,7 @@ module Alchemy
187
184
  it "should update published_at" do
188
185
  expect {
189
186
  page.update_attributes!(public: true)
190
- }.to change {page.read_attribute(:published_at) }
187
+ }.to change { page.read_attribute(:published_at) }
191
188
  end
192
189
 
193
190
  it "should not update already set published_at" do
@@ -207,9 +204,9 @@ module Alchemy
207
204
  end
208
205
 
209
206
  context 'after_move' do
210
- let(:parent_1) { FactoryGirl.create(:page, name: 'Parent 1', visible: true) }
211
- let(:parent_2) { FactoryGirl.create(:page, name: 'Parent 2', visible: true) }
212
- let(:page) { FactoryGirl.create(:page, parent_id: parent_1.id, name: 'Page', visible: true) }
207
+ let(:parent_1) { create(:alchemy_page, name: 'Parent 1', visible: true) }
208
+ let(:parent_2) { create(:alchemy_page, name: 'Parent 2', visible: true) }
209
+ let(:page) { create(:alchemy_page, parent_id: parent_1.id, name: 'Page', visible: true) }
213
210
 
214
211
  it "updates the urlname" do
215
212
  expect(page.urlname).to eq('parent-1/page')
@@ -218,7 +215,7 @@ module Alchemy
218
215
  end
219
216
 
220
217
  context 'of an external page' do
221
- let(:external) { FactoryGirl.create(:page, parent_id: parent_1.id, name: 'external', page_layout: 'external', urlname: 'http://google.com') }
218
+ let(:external) { create(:alchemy_page, parent_id: parent_1.id, name: 'external', page_layout: 'external', urlname: 'http://google.com') }
222
219
 
223
220
  it "the urlname does not get updated" do
224
221
  external.move_to_child_of parent_2
@@ -227,57 +224,79 @@ module Alchemy
227
224
  end
228
225
  end
229
226
 
230
- context "a normal page" do
231
- before do
232
- @page = FactoryGirl.build(:page, language_code: nil, language: klingonian, do_not_autogenerate: false)
227
+ context "Saving a normal page" do
228
+ let(:page) do
229
+ build(:alchemy_page, language_code: nil, language: klingon, do_not_autogenerate: false)
233
230
  end
234
231
 
235
- it "should set the language code" do
236
- @page.save
237
- expect(@page.language_code).to eq("kl")
232
+ it "sets the language code" do
233
+ page.save!
234
+ expect(page.language_code).to eq("kl")
238
235
  end
239
236
 
240
- it "should autogenerate the elements" do
241
- @page.save
242
- expect(@page.elements).not_to be_empty
237
+ it "autogenerates the elements" do
238
+ page.save!
239
+ expect(page.elements).not_to be_empty
243
240
  end
244
241
 
245
- it "should not autogenerate elements that are already on the page" do
246
- @page.elements << FactoryGirl.create(:element, name: 'header')
247
- @page.save
248
- expect(@page.elements.select { |e| e.name == 'header' }.length).to eq(1)
242
+ context 'with elements already on the page' do
243
+ before do
244
+ page.elements << create(:alchemy_element, name: 'header')
245
+ end
246
+
247
+ it "does not autogenerate" do
248
+ page.save!
249
+ expect(page.elements.select { |e| e.name == 'header' }.length).to eq(1)
250
+ end
249
251
  end
250
252
 
251
253
  context "with cells" do
252
254
  before do
253
- allow(@page).to receive(:definition).and_return({'name' => 'with_cells', 'cells' => ['header', 'main']})
255
+ allow(page).to receive(:definition) do
256
+ {
257
+ 'cells' => %w(header main),
258
+ 'autogenerate' => %w(article)
259
+ }
260
+ end
254
261
  end
255
262
 
256
- it "should have the generated elements in their cells" do
257
- allow(@page).to receive(:cell_definitions).and_return([{'name' => 'header', 'elements' => ['article']}])
258
- @page.save
259
- expect(@page.cells.where(name: 'header').first.elements).not_to be_empty
263
+ context 'with elements defined in cells' do
264
+ before do
265
+ allow(page).to receive(:cell_definitions) do
266
+ [{'name' => 'header', 'elements' => %w(article)}]
267
+ end
268
+ end
269
+
270
+ it "has the generated elements in their cells" do
271
+ page.save!
272
+ expect(page.cells.where(name: 'header').first.elements).not_to be_empty
273
+ end
260
274
  end
261
275
 
262
276
  context "and no elements in cell definitions" do
277
+ before do
278
+ allow(page).to receive(:cell_definitions) do
279
+ [{'name' => 'header', 'elements' => []}]
280
+ end
281
+ end
282
+
263
283
  it "should have the elements in the nil cell" do
264
- allow(@page).to receive(:cell_definitions).and_return([{'name' => 'header', 'elements' => []}])
265
- @page.save
266
- expect(@page.cells.collect(&:elements).flatten).to be_empty
284
+ page.save!
285
+ expect(page.cells.collect(&:elements).flatten).to be_empty
267
286
  end
268
287
  end
269
288
  end
270
289
 
271
290
  context "with children getting restricted set to true" do
272
291
  before do
273
- @page.save
274
- @child1 = FactoryGirl.create(:page, name: 'Child 1', parent_id: @page.id)
275
- @page.reload
276
- @page.restricted = true
277
- @page.save
292
+ page.save
293
+ @child1 = create(:alchemy_page, name: 'Child 1', parent_id: page.id)
294
+ page.reload
295
+ page.restricted = true
296
+ page.save
278
297
  end
279
298
 
280
- it "should restrict all its children" do
299
+ it "restricts all its children" do
281
300
  @child1.reload
282
301
  expect(@child1.restricted?).to be_truthy
283
302
  end
@@ -285,39 +304,37 @@ module Alchemy
285
304
 
286
305
  context "with restricted parent gets created" do
287
306
  before do
288
- @page.save
289
- @page.parent.update_attributes(restricted: true)
290
- @new_page = FactoryGirl.create(:page, name: 'New Page', parent_id: @page.id)
307
+ page.save
308
+ page.parent.update!(restricted: true)
309
+ @new_page = create(:alchemy_page, name: 'New Page', parent_id: page.id)
291
310
  end
292
311
 
293
- it "should also be restricted" do
312
+ it "is also be restricted" do
294
313
  expect(@new_page.restricted?).to be_truthy
295
314
  end
296
315
  end
297
316
 
298
317
  context "with do_not_autogenerate set to true" do
299
318
  before do
300
- @page.do_not_autogenerate = true
319
+ page.do_not_autogenerate = true
301
320
  end
302
321
 
303
322
  it "should not autogenerate the elements" do
304
- @page.save
305
- expect(@page.elements).to be_empty
323
+ page.save
324
+ expect(page.elements).to be_empty
306
325
  end
307
326
  end
308
327
  end
309
328
 
310
- context "a systempage" do
311
- before do
312
- @page = FactoryGirl.create(:systempage)
313
- end
329
+ context "Creating a systempage" do
330
+ let!(:page) { create(:alchemy_page, :system) }
314
331
 
315
- it "should not get the language code for language" do
316
- expect(@page.language_code).to be_nil
332
+ it "does not get the language code from language" do
333
+ expect(page.language_code).to be_nil
317
334
  end
318
335
 
319
- it "should not autogenerate the elements" do
320
- expect(@page.elements).to be_empty
336
+ it "does not autogenerate the elements" do
337
+ expect(page.elements).to be_empty
321
338
  end
322
339
  end
323
340
 
@@ -325,9 +342,9 @@ module Alchemy
325
342
  let(:news_element) { news_page.elements.find_by(name: 'news') }
326
343
 
327
344
  it "all elements not allowed on this page should be trashed" do
328
- expect(news_page.elements.trashed).to be_empty
345
+ expect(news_page.trashed_elements).to be_empty
329
346
  news_page.update_attributes(page_layout: 'standard')
330
- trashed = news_page.elements.trashed.pluck(:name)
347
+ trashed = news_page.trashed_elements.pluck(:name)
331
348
  expect(trashed).to eq(['news'])
332
349
  expect(trashed).to_not include('article', 'header')
333
350
  end
@@ -339,14 +356,13 @@ module Alchemy
339
356
  end
340
357
  end
341
358
 
342
-
343
359
  # ClassMethods (a-z)
344
360
 
345
361
  describe '.all_from_clipboard_for_select' do
346
362
  context "with clipboard holding pages having non unique page layout" do
347
363
  it "should return the pages" do
348
- page_1 = FactoryGirl.create(:page, language: language)
349
- page_2 = FactoryGirl.create(:page, language: language, name: 'Another page')
364
+ page_1 = create(:alchemy_page, language: language)
365
+ page_2 = create(:alchemy_page, language: language, name: 'Another page')
350
366
  clipboard = [
351
367
  {'id' => page_1.id.to_s, 'action' => 'copy'},
352
368
  {'id' => page_2.id.to_s, 'action' => 'copy'}
@@ -357,7 +373,7 @@ module Alchemy
357
373
 
358
374
  context "with clipboard holding a page having unique page layout" do
359
375
  it "should not return any pages" do
360
- page_1 = FactoryGirl.create(:page, language: language, page_layout: 'contact')
376
+ page_1 = create(:alchemy_page, language: language, page_layout: 'contact')
361
377
  clipboard = [
362
378
  {'id' => page_1.id.to_s, 'action' => 'copy'}
363
379
  ]
@@ -367,8 +383,8 @@ module Alchemy
367
383
 
368
384
  context "with clipboard holding two pages. One having a unique page layout." do
369
385
  it "should return one page" do
370
- page_1 = FactoryGirl.create(:page, language: language, page_layout: 'standard')
371
- page_2 = FactoryGirl.create(:page, name: 'Another page', language: language, page_layout: 'contact')
386
+ page_1 = create(:alchemy_page, language: language, page_layout: 'standard')
387
+ page_2 = create(:alchemy_page, name: 'Another page', language: language, page_layout: 'contact')
372
388
  clipboard = [
373
389
  {'id' => page_1.id.to_s, 'action' => 'copy'},
374
390
  {'id' => page_2.id.to_s, 'action' => 'copy'}
@@ -378,26 +394,26 @@ module Alchemy
378
394
  end
379
395
  end
380
396
 
381
- describe '.all_locked' do
397
+ describe '.locked' do
382
398
  it "should return 1 page that is blocked by a user at the moment" do
383
- FactoryGirl.create(:public_page, locked: true, name: 'First Public Child', parent_id: language_root.id, language: language)
384
- expect(Page.all_locked.size).to eq(1)
399
+ create(:alchemy_page, :public, locked: true, name: 'First Public Child', parent_id: language_root.id, language: language)
400
+ expect(Page.locked.size).to eq(1)
385
401
  end
386
402
  end
387
403
 
388
- describe '.all_locked_by' do
404
+ describe '.locked_by' do
389
405
  let(:user) { double(:user, id: 1, class: DummyUser) }
390
406
 
391
407
  before do
392
- FactoryGirl.create(:public_page, locked: true, locked_by: 53) # This page must not be part of the collection
408
+ create(:alchemy_page, :public, locked: true, locked_by: 53) # This page must not be part of the collection
393
409
  allow(user.class)
394
410
  .to receive(:primary_key)
395
411
  .and_return('id')
396
412
  end
397
413
 
398
414
  it "should return the correct page collection blocked by a certain user" do
399
- page = FactoryGirl.create(:public_page, locked: true, locked_by: 1)
400
- expect(Page.all_locked_by(user).pluck(:id)).to eq([page.id])
415
+ page = create(:alchemy_page, :public, locked: true, locked_by: 1)
416
+ expect(Page.locked_by(user).pluck(:id)).to eq([page.id])
401
417
  end
402
418
 
403
419
  context 'with user class having a different primary key' do
@@ -410,16 +426,16 @@ module Alchemy
410
426
  end
411
427
 
412
428
  it "should return the correct page collection blocked by a certain user" do
413
- page = FactoryGirl.create(:public_page, locked: true, locked_by: 123)
414
- expect(Page.all_locked_by(user).pluck(:id)).to eq([page.id])
429
+ page = create(:alchemy_page, :public, locked: true, locked_by: 123)
430
+ expect(Page.locked_by(user).pluck(:id)).to eq([page.id])
415
431
  end
416
432
  end
417
433
  end
418
434
 
419
435
  describe '.ancestors_for' do
420
436
  let(:lang_root) { Page.language_root_for(Language.default.id) }
421
- let(:parent) { create(:public_page) }
422
- let(:page) { create(:public_page, parent_id: parent.id) }
437
+ let(:parent) { create(:alchemy_page, :public) }
438
+ let(:page) { create(:alchemy_page, :public, parent_id: parent.id) }
423
439
 
424
440
  it "returns an array of all parents including self" do
425
441
  expect(Page.ancestors_for(page)).to eq([lang_root, parent, page])
@@ -437,28 +453,56 @@ module Alchemy
437
453
  end
438
454
 
439
455
  describe '.contentpages' do
440
- before do
441
- layoutroot = Page.find_or_create_layout_root_for(klingonian.id)
442
- @layoutpage = FactoryGirl.create(:public_page, name: 'layoutpage', layoutpage: true, parent_id: layoutroot.id, language: klingonian)
443
- @klingonian_lang_root = FactoryGirl.create(:language_root_page, name: 'klingonian_lang_root', layoutpage: nil, language: klingonian)
444
- @contentpage = FactoryGirl.create(:public_page, name: 'contentpage', parent_id: language_root.id, language: language)
456
+ let!(:layoutroot) do
457
+ Page.find_or_create_layout_root_for(klingon.id)
458
+ end
459
+
460
+ let!(:layoutpage) do
461
+ create :alchemy_page, :public, {
462
+ name: 'layoutpage',
463
+ layoutpage: true,
464
+ parent_id: layoutroot.id,
465
+ language: klingon
466
+ }
445
467
  end
446
468
 
447
- it "should return a collection of contentpages" do
448
- expect(Page.contentpages.to_a).to include(language_root, @klingonian_lang_root, @contentpage)
469
+ let!(:klingon_lang_root) do
470
+ create :alchemy_page, :language_root, {
471
+ name: 'klingon_lang_root',
472
+ layoutpage: nil,
473
+ language: klingon
474
+ }
475
+ end
476
+
477
+ let!(:contentpage) do
478
+ create :alchemy_page, :public, {
479
+ name: 'contentpage',
480
+ parent_id: language_root.id,
481
+ language: language
482
+ }
449
483
  end
450
484
 
451
- it "should not contain pages with attribute :layoutpage set to true" do
485
+ it "returns a collection of contentpages" do
486
+ expect(Page.contentpages.to_a).to include(
487
+ language_root,
488
+ klingon_lang_root,
489
+ contentpage
490
+ )
491
+ end
492
+
493
+ it "does not contain pages with attribute :layoutpage set to true" do
452
494
  expect(Page.contentpages.to_a.select { |p| p.layoutpage == true }).to be_empty
453
495
  end
454
496
 
455
- it "should contain pages with attribute :layoutpage set to nil" do
456
- expect(Page.contentpages.to_a.select { |p| p.layoutpage == nil }).to include(@klingonian_lang_root)
497
+ it "contains pages with attribute :layoutpage set to nil" do
498
+ expect(Page.contentpages.to_a.select do |page|
499
+ page.layoutpage.nil?
500
+ end).to include(klingon_lang_root)
457
501
  end
458
502
  end
459
503
 
460
504
  describe '.copy' do
461
- let(:page) { FactoryGirl.create(:page, name: 'Source') }
505
+ let(:page) { create(:alchemy_page, name: 'Source') }
462
506
  subject { Page.copy(page) }
463
507
 
464
508
  it "the copy should have added (copy) to name" do
@@ -478,7 +522,7 @@ module Alchemy
478
522
  end
479
523
 
480
524
  context "page with elements" do
481
- before { page.elements << FactoryGirl.create(:element) }
525
+ before { page.elements << create(:alchemy_element) }
482
526
 
483
527
  it "the copy should have source elements" do
484
528
  expect(subject.elements).not_to be_empty
@@ -488,7 +532,7 @@ module Alchemy
488
532
 
489
533
  context "page with trashed elements" do
490
534
  before do
491
- page.elements << FactoryGirl.create(:element)
535
+ page.elements << create(:alchemy_element)
492
536
  page.elements.first.trash!
493
537
  end
494
538
 
@@ -498,7 +542,7 @@ module Alchemy
498
542
  end
499
543
 
500
544
  context "page with cells" do
501
- before { page.cells << FactoryGirl.create(:cell) }
545
+ before { page.cells << create(:alchemy_cell) }
502
546
 
503
547
  it "the copy should have source cells" do
504
548
  expect(subject.cells).not_to be_empty
@@ -508,7 +552,7 @@ module Alchemy
508
552
 
509
553
  context "page with autogenerate elements" do
510
554
  before do
511
- page = FactoryGirl.create(:page)
555
+ page = create(:alchemy_page)
512
556
  allow(page).to receive(:definition).and_return({'name' => 'standard', 'elements' => ['headline'], 'autogenerate' => ['headline']})
513
557
  end
514
558
 
@@ -519,6 +563,7 @@ module Alchemy
519
563
 
520
564
  context "with different page name given" do
521
565
  subject { Page.copy(page, {name: 'Different name'}) }
566
+
522
567
  it "should take this name" do
523
568
  expect(subject.name).to eq('Different name')
524
569
  end
@@ -528,12 +573,12 @@ module Alchemy
528
573
  describe '.create' do
529
574
  context "before/after filter" do
530
575
  it "should automatically set the title from its name" do
531
- page = FactoryGirl.create(:page, name: 'My Testpage', language: language, parent_id: language_root.id)
576
+ page = create(:alchemy_page, name: 'My Testpage', language: language, parent_id: language_root.id)
532
577
  expect(page.title).to eq('My Testpage')
533
578
  end
534
579
 
535
580
  it "should get a webfriendly urlname" do
536
- page = FactoryGirl.create(:page, name: 'klingon$&stößel ', language: language, parent_id: language_root.id)
581
+ page = create(:alchemy_page, name: 'klingon$&stößel ', language: language, parent_id: language_root.id)
537
582
  expect(page.urlname).to eq('klingon-stoessel')
538
583
  end
539
584
 
@@ -545,22 +590,22 @@ module Alchemy
545
590
  end
546
591
 
547
592
  it "should generate a three letter urlname from two letter name" do
548
- page = FactoryGirl.create(:page, name: 'Au', language: language, parent_id: language_root.id)
593
+ page = create(:alchemy_page, name: 'Au', language: language, parent_id: language_root.id)
549
594
  expect(page.urlname).to eq('-au')
550
595
  end
551
596
 
552
597
  it "should generate a three letter urlname from two letter name with umlaut" do
553
- page = FactoryGirl.create(:page, name: 'Aü', language: language, parent_id: language_root.id)
598
+ page = create(:alchemy_page, name: 'Aü', language: language, parent_id: language_root.id)
554
599
  expect(page.urlname).to eq('aue')
555
600
  end
556
601
 
557
602
  it "should generate a three letter urlname from one letter name" do
558
- page = FactoryGirl.create(:page, name: 'A', language: language, parent_id: language_root.id)
603
+ page = create(:alchemy_page, name: 'A', language: language, parent_id: language_root.id)
559
604
  expect(page.urlname).to eq('--a')
560
605
  end
561
606
 
562
607
  it "should add a user stamper" do
563
- page = FactoryGirl.create(:page, name: 'A', language: language, parent_id: language_root.id)
608
+ page = create(:alchemy_page, name: 'A', language: language, parent_id: language_root.id)
564
609
  expect(page.class.stamper_class.to_s).to eq('DummyUser')
565
610
  end
566
611
 
@@ -613,44 +658,51 @@ module Alchemy
613
658
 
614
659
  describe '.language_roots' do
615
660
  it "should return 1 language_root" do
616
- FactoryGirl.create(:public_page, name: 'First Public Child', parent_id: language_root.id, language: language)
661
+ create(:alchemy_page, :public, name: 'First Public Child', parent_id: language_root.id, language: language)
617
662
  expect(Page.language_roots.size).to eq(1)
618
663
  end
619
664
  end
620
665
 
621
666
  describe '.layoutpages' do
622
667
  it "should return 1 layoutpage" do
623
- FactoryGirl.create(:public_page, layoutpage: true, name: 'Layoutpage', parent_id: rootpage.id, language: language)
668
+ create(:alchemy_page, :public, layoutpage: true, name: 'Layoutpage', parent_id: rootpage.id, language: language)
624
669
  expect(Page.layoutpages.size).to eq(1)
625
670
  end
626
671
  end
627
672
 
628
673
  describe '.not_locked' do
629
674
  it "should return pages that are not blocked by a user at the moment" do
630
- FactoryGirl.create(:public_page, locked: true, name: 'First Public Child', parent_id: language_root.id, language: language)
631
- FactoryGirl.create(:public_page, name: 'Second Public Child', parent_id: language_root.id, language: language)
675
+ create(:alchemy_page, :public, locked: true, name: 'First Public Child', parent_id: language_root.id, language: language)
676
+ create(:alchemy_page, :public, name: 'Second Public Child', parent_id: language_root.id, language: language)
632
677
  expect(Page.not_locked.size).to eq(3)
633
678
  end
634
679
  end
635
680
 
636
681
  describe '.not_restricted' do
637
682
  it "should return 2 accessible pages" do
638
- FactoryGirl.create(:public_page, name: 'First Public Child', restricted: true, parent_id: language_root.id, language: language)
683
+ create(:alchemy_page, :public, name: 'First Public Child', restricted: true, parent_id: language_root.id, language: language)
639
684
  expect(Page.not_restricted.size).to eq(2)
640
685
  end
641
686
  end
642
687
 
643
688
  describe '.public' do
644
689
  it "should return pages that are public" do
645
- FactoryGirl.create(:public_page, name: 'First Public Child', parent_id: language_root.id, language: language)
646
- FactoryGirl.create(:public_page, name: 'Second Public Child', parent_id: language_root.id, language: language)
690
+ create(:alchemy_page, :public, name: 'First Public Child', parent_id: language_root.id, language: language)
691
+ create(:alchemy_page, :public, name: 'Second Public Child', parent_id: language_root.id, language: language)
647
692
  expect(Page.published.size).to eq(3)
648
693
  end
649
694
  end
650
695
 
696
+ describe '.public_language_roots' do
697
+ it "should return pages that public language roots" do
698
+ create(:alchemy_page, :public, name: 'First Public Child', parent_id: language_root.id, language: language)
699
+ expect(Page.public_language_roots.size).to eq(1)
700
+ end
701
+ end
702
+
651
703
  describe '.restricted' do
652
704
  it "should return 1 restricted page" do
653
- FactoryGirl.create(:public_page, name: 'First Public Child', restricted: true, parent_id: language_root.id, language: language)
705
+ create(:alchemy_page, :public, name: 'First Public Child', restricted: true, parent_id: language_root.id, language: language)
654
706
  expect(Page.restricted.size).to eq(1)
655
707
  end
656
708
  end
@@ -663,16 +715,15 @@ module Alchemy
663
715
 
664
716
  describe '.visible' do
665
717
  it "should return 1 visible page" do
666
- FactoryGirl.create(:public_page, name: 'First Public Child', visible: true, parent_id: language_root.id, language: language)
718
+ create(:alchemy_page, :public, name: 'First Public Child', visible: true, parent_id: language_root.id, language: language)
667
719
  expect(Page.visible.size).to eq(1)
668
720
  end
669
721
  end
670
722
 
671
-
672
723
  # InstanceMethods (a-z)
673
724
 
674
725
  describe '#available_element_definitions' do
675
- let(:page) { FactoryGirl.build_stubbed(:public_page) }
726
+ let(:page) { build_stubbed(:alchemy_page, :public) }
676
727
 
677
728
  it "returns all element definitions of available elements" do
678
729
  expect(page.available_element_definitions).to be_an(Array)
@@ -680,7 +731,7 @@ module Alchemy
680
731
  end
681
732
 
682
733
  context "with unique elements already on page" do
683
- let(:element) { FactoryGirl.build_stubbed(:unique_element) }
734
+ let(:element) { build_stubbed(:alchemy_element, :unique) }
684
735
 
685
736
  before do
686
737
  allow(page)
@@ -695,11 +746,13 @@ module Alchemy
695
746
  end
696
747
 
697
748
  context 'limited amount' do
698
- let(:page) { FactoryGirl.build_stubbed(:page, page_layout: 'columns') }
699
- let(:unique_element) { FactoryGirl.build_stubbed(:unique_element, name: 'unique_headline') }
700
- let(:element_1) { FactoryGirl.build_stubbed(:element, name: 'column_headline') }
701
- let(:element_2) { FactoryGirl.build_stubbed(:element, name: 'column_headline') }
702
- let(:element_3) { FactoryGirl.build_stubbed(:element, name: 'column_headline') }
749
+ let(:page) { build_stubbed(:alchemy_page, page_layout: 'columns') }
750
+ let(:unique_element) do
751
+ build_stubbed(:alchemy_element, :unique, name: 'unique_headline')
752
+ end
753
+ let(:element_1) { build_stubbed(:alchemy_element, name: 'column_headline') }
754
+ let(:element_2) { build_stubbed(:alchemy_element, name: 'column_headline') }
755
+ let(:element_3) { build_stubbed(:alchemy_element, name: 'column_headline') }
703
756
 
704
757
  before {
705
758
  allow(Element).to receive(:definitions).and_return([
@@ -746,7 +799,7 @@ module Alchemy
746
799
  end
747
800
 
748
801
  describe '#available_element_names' do
749
- let(:page) { FactoryGirl.build_stubbed(:page) }
802
+ let(:page) { build_stubbed(:alchemy_page) }
750
803
 
751
804
  it "returns all names of elements that could be placed on current page" do
752
805
  page.available_element_names == %w(header article)
@@ -755,7 +808,7 @@ module Alchemy
755
808
 
756
809
  describe '#cache_key' do
757
810
  let(:page) do
758
- stub_model(Page, updated_at: Time.now, published_at: Time.now - 1.week)
811
+ stub_model(Page, updated_at: Time.current, published_at: Time.current - 1.week)
759
812
  end
760
813
 
761
814
  subject { page.cache_key }
@@ -779,14 +832,14 @@ module Alchemy
779
832
 
780
833
  describe '#cell_definitions' do
781
834
  before do
782
- @page = FactoryGirl.build(:page, page_layout: 'foo')
835
+ @page = build(:alchemy_page, page_layout: 'foo')
783
836
  allow(@page).to receive(:definition).and_return({'name' => "foo", 'cells' => ["foo_cell"]})
784
- @cell_descriptions = [{'name' => "foo_cell", 'elements' => ["1", "2"]}]
785
- allow(Cell).to receive(:definitions).and_return(@cell_descriptions)
837
+ @cell_definitions = [{'name' => "foo_cell", 'elements' => ["1", "2"]}]
838
+ allow(Cell).to receive(:definitions).and_return(@cell_definitions)
786
839
  end
787
840
 
788
841
  it "should return all cell definitions for its page_layout" do
789
- expect(@page.cell_definitions).to eq(@cell_descriptions)
842
+ expect(@page.cell_definitions).to eq(@cell_definitions)
790
843
  end
791
844
 
792
845
  it "should return empty array if no cells defined in page layout" do
@@ -806,8 +859,86 @@ module Alchemy
806
859
  end
807
860
  end
808
861
 
862
+ describe "#elements" do
863
+ let(:page) { create(:alchemy_page) }
864
+ let!(:element_1) { create(:alchemy_element, page: page) }
865
+ let!(:element_2) { create(:alchemy_element, page: page) }
866
+ let!(:element_3) { create(:alchemy_element, page: page) }
867
+
868
+ before do
869
+ element_3.move_to_top
870
+ end
871
+
872
+ it 'returns a ordered active record collection of elements on that page' do
873
+ expect(page.elements).to eq([element_3, element_1, element_2])
874
+ end
875
+
876
+ context 'with nestable elements' do
877
+ let(:nestable_element) { create(:alchemy_element, :with_nestable_elements) }
878
+
879
+ before do
880
+ nestable_element.nested_elements << create(:alchemy_element, name: 'slide')
881
+ page.elements << nestable_element
882
+ end
883
+
884
+ it 'does not contain nested elements of an element' do
885
+ expect(nestable_element.nested_elements).to_not be_empty
886
+ expect(page.elements).to_not include(nestable_element.nested_elements.first)
887
+ end
888
+ end
889
+ end
890
+
891
+ describe "#descendent_elements" do
892
+ let!(:page) do
893
+ create(:alchemy_page)
894
+ end
895
+
896
+ let!(:element_1) do
897
+ create(:alchemy_element, page_id: page.id)
898
+ end
899
+
900
+ let!(:element_2) do
901
+ create(:alchemy_element, :with_nestable_elements, page_id: page.id, parent_element_id: element_1.id)
902
+ end
903
+
904
+ let!(:element_3) do
905
+ create(:alchemy_element, page_id: page.id)
906
+ end
907
+
908
+ it 'returns an active record collection of all elements including nested elements on that page' do
909
+ expect(page.descendent_elements.count).to eq(3)
910
+ end
911
+ end
912
+
913
+ describe "#descendent_contents" do
914
+ let!(:page) do
915
+ create(:alchemy_page)
916
+ end
917
+
918
+ let!(:element_1) do
919
+ create(:alchemy_element, :with_nestable_elements, :with_contents, name: 'slider', page_id: page.id)
920
+ end
921
+
922
+ let!(:element_2) do
923
+ create :alchemy_element,
924
+ :with_contents, {
925
+ name: 'slide',
926
+ page_id: page.id,
927
+ parent_element_id: element_1.id
928
+ }
929
+ end
930
+
931
+ let!(:element_3) do
932
+ create(:alchemy_element, :with_contents, name: 'slide', page_id: page.id)
933
+ end
934
+
935
+ it 'returns an active record collection of all content including nested elements on that page' do
936
+ expect(page.descendent_contents.count).to eq(2)
937
+ end
938
+ end
939
+
809
940
  describe '#element_definitions' do
810
- let(:page) { FactoryGirl.build_stubbed(:page) }
941
+ let(:page) { build_stubbed(:alchemy_page) }
811
942
  subject { page.element_definitions }
812
943
  before { expect(Element).to receive(:definitions).and_return([{'name' => 'article'}, {'name' => 'header'}]) }
813
944
 
@@ -818,7 +949,7 @@ module Alchemy
818
949
  end
819
950
 
820
951
  describe '#element_definitions_by_name' do
821
- let(:page) { FactoryGirl.build_stubbed(:public_page) }
952
+ let(:page) { build_stubbed(:alchemy_page, :public) }
822
953
 
823
954
  context "with no name given" do
824
955
  it "returns empty array" do
@@ -842,103 +973,78 @@ module Alchemy
842
973
  end
843
974
 
844
975
  describe '#element_definition_names' do
845
- let(:page) { FactoryGirl.build_stubbed(:public_page) }
976
+ let(:page) { build_stubbed(:alchemy_page, :public) }
846
977
 
847
- context "with assigned elements from page and cell definition" do
848
- before do
849
- allow(page).to receive(:element_names_from_page_definition).and_return(['header', 'article'])
850
- allow(page).to receive(:element_names_from_cell_definition).and_return(['search'])
851
- end
978
+ subject { page.element_definition_names }
852
979
 
853
- it "returns the combined element names" do
854
- expect(page.element_definition_names).to eq(%w(header article search))
855
- end
856
-
857
- context "when cell definition contains same element name as page definition" do
858
- before do
859
- allow(page).to receive(:element_names_from_page_definition).and_return(['header', 'article'])
860
- allow(page).to receive(:element_names_from_cell_definition).and_return(['header', 'search'])
861
- end
862
-
863
- it "returns no duplicates" do
864
- expect(page.element_definition_names).to eq(%w(header article search))
865
- end
866
- end
980
+ before do
981
+ allow(page).to receive(:definition) { page_definition }
982
+ allow(page).to receive(:cell_definitions) { cell_definitions }
867
983
  end
868
984
 
869
- context "without assigned elements from page definition" do
870
- before do
871
- allow(page).to receive(:element_names_from_page_definition).and_return([])
872
- allow(page).to receive(:element_names_from_cell_definition).and_return(['article'])
985
+ context "with elements only assigned in page definition" do
986
+ let(:page_definition) do
987
+ {'elements' => %w(article)}
873
988
  end
874
989
 
875
- it "returns an array" do
876
- expect(page.element_definition_names).to be_an(Array)
990
+ let(:cell_definitions) { [] }
991
+
992
+ it "returns an array of the page's element names" do
993
+ is_expected.to eq %w(article)
877
994
  end
878
995
  end
879
996
 
880
- context "without assigned elements from cell definition" do
997
+ context "with elements assigned only in cell definition" do
881
998
  before do
882
- allow(page).to receive(:element_names_from_page_definition).and_return(['article'])
883
- allow(page).to receive(:element_names_from_cell_definition).and_return([])
999
+ allow(page).to receive(:definition).and_return({})
1000
+ allow(page).to receive(:cell_definitions) do
1001
+ [{'elements' => ['search']}]
1002
+ end
884
1003
  end
885
1004
 
886
- it "returns an array" do
887
- expect(page.element_definition_names).to be_an(Array)
1005
+ it "returns an array of the cell's element names" do
1006
+ is_expected.to eq(['search'])
888
1007
  end
889
1008
  end
890
- end
891
-
892
- describe "#element_names_from_page_definition" do
893
- let(:page) { FactoryGirl.build_stubbed(:public_page) }
894
1009
 
895
- context "with assigned elements from page definition" do
896
- before do
897
- allow(page).to receive(:definition).and_return(
898
- {'name' => 'test_page', 'elements' => ['article']}
899
- )
1010
+ context "with elements assigned in page and cell definition" do
1011
+ let(:page_definition) do
1012
+ {'elements' => %w(header article)}
900
1013
  end
901
1014
 
902
- it "returns an array of the page's element names" do
903
- expect(page.element_names_from_page_definition).to eq(['article'])
1015
+ let(:cell_definitions) do
1016
+ [{'elements' => %w(search)}]
904
1017
  end
905
- end
906
1018
 
907
- context "without assigned elements from page definition" do
908
- before do
909
- allow(page).to receive(:definition).and_return({})
910
- end
911
-
912
- it "returns an array" do
913
- expect(page.element_names_from_page_definition).to be_an(Array)
1019
+ it "returns the combined element names" do
1020
+ is_expected.to eq %w(header article search)
914
1021
  end
915
- end
916
- end
917
1022
 
918
- describe "#element_names_from_cell_definition" do
919
- let(:page) { FactoryGirl.build_stubbed(:public_page) }
1023
+ context "and cell definition contains same element name as page definition" do
1024
+ let(:page_definition) do
1025
+ {'elements' => %w(header article)}
1026
+ end
920
1027
 
921
- context "with assigned elements from cell definition" do
922
- before do
923
- allow(page).to receive(:cell_definitions).and_return([
924
- {'name' => 'header', 'elements' => ['article']}
925
- ])
926
- end
1028
+ let(:cell_definitions) do
1029
+ [{'elements' => %w(header search)}]
1030
+ end
927
1031
 
928
- it "returns an array of the cell's element names" do
929
- expect(page.element_names_from_cell_definition).to eq(['article'])
1032
+ it "includes no duplicates" do
1033
+ is_expected.to eq %w(header article search)
1034
+ end
930
1035
  end
931
1036
  end
932
1037
 
933
- context "without assigned elements from cell definition" do
934
- it "returns an array" do
935
- expect(page.element_names_from_cell_definition).to be_an(Array)
936
- end
1038
+ context "without elements assigned in page definition or cell definition" do
1039
+ let(:page_definition) { {} }
1040
+ let(:cell_definitions) { [] }
1041
+
1042
+ it { is_expected.to eq([]) }
937
1043
  end
938
1044
  end
939
1045
 
940
1046
  describe '#elements_grouped_by_cells' do
941
- let(:page) { FactoryGirl.create(:public_page, do_not_autogenerate: false) }
1047
+ let(:page) { create(:alchemy_page, :public, do_not_autogenerate: false) }
942
1048
 
943
1049
  before do
944
1050
  allow(PageLayout).to receive(:get).and_return({
@@ -965,16 +1071,28 @@ module Alchemy
965
1071
  end
966
1072
 
967
1073
  describe '#feed_elements' do
968
- it "should return all rss feed elements" do
1074
+ let(:news_element) { create(:alchemy_element, name: 'news', public: false, page: news_page) }
1075
+
1076
+ it "should return all published rss feed elements" do
969
1077
  expect(news_page.feed_elements).not_to be_empty
970
- expect(news_page.feed_elements).to eq(Element.where(name: 'news').to_a)
1078
+ expect(news_page.feed_elements).to eq(Element.where(name: 'news').available.to_a)
1079
+ end
1080
+
1081
+ it "should not return unpublished rss feed elements" do
1082
+ expect(news_page.feed_elements).not_to include(news_element)
1083
+ end
1084
+
1085
+ it "should not return trashed rss feed elements" do
1086
+ news_element.update(public: true)
1087
+ news_element.trash!
1088
+ expect(news_page.feed_elements).not_to include(news_element)
971
1089
  end
972
1090
  end
973
1091
 
974
1092
  describe '#find_elements' do
975
1093
  before do
976
- FactoryGirl.create(:element, public: false, page: public_page)
977
- FactoryGirl.create(:element, public: false, page: public_page)
1094
+ create(:alchemy_element, public: false, page: public_page)
1095
+ create(:alchemy_element, public: false, page: public_page)
978
1096
  end
979
1097
 
980
1098
  context "with show_non_public argument TRUE" do
@@ -1000,7 +1118,7 @@ module Alchemy
1000
1118
  end
1001
1119
 
1002
1120
  context "with options[:from_cell]" do
1003
- let(:element) { FactoryGirl.build_stubbed(:element) }
1121
+ let(:element) { build_stubbed(:alchemy_element) }
1004
1122
 
1005
1123
  context "given as String" do
1006
1124
  context 'with elements present' do
@@ -1016,7 +1134,7 @@ module Alchemy
1016
1134
  end
1017
1135
 
1018
1136
  context "that can not be found" do
1019
- let(:elements) {[]}
1137
+ let(:elements) { [] }
1020
1138
 
1021
1139
  before do
1022
1140
  allow(elements)
@@ -1037,7 +1155,7 @@ module Alchemy
1037
1155
  end
1038
1156
 
1039
1157
  context "given as cell object" do
1040
- let(:cell) { FactoryGirl.build_stubbed(:cell, page: public_page) }
1158
+ let(:cell) { build_stubbed(:alchemy_cell, page: public_page) }
1041
1159
 
1042
1160
  it "returns only the elements from given cell" do
1043
1161
  expect(cell)
@@ -1051,7 +1169,7 @@ module Alchemy
1051
1169
 
1052
1170
  context "with show_non_public argument FALSE" do
1053
1171
  it "should return all elements from empty arguments" do
1054
- expect(public_page.find_elements().to_a).to eq(public_page.elements.published.to_a)
1172
+ expect(public_page.find_elements.to_a).to eq(public_page.elements.published.to_a)
1055
1173
  end
1056
1174
 
1057
1175
  it "should only return the public elements passed as options[:only]" do
@@ -1074,11 +1192,11 @@ module Alchemy
1074
1192
 
1075
1193
  describe '#first_public_child' do
1076
1194
  before do
1077
- FactoryGirl.create(:page, name: "First child", language: language, public: false, parent_id: language_root.id)
1195
+ create(:alchemy_page, name: "First child", language: language, public: false, parent_id: language_root.id)
1078
1196
  end
1079
1197
 
1080
1198
  it "should return first_public_child" do
1081
- first_public_child = FactoryGirl.create(:public_page, name: "First public child", language: language, parent_id: language_root.id)
1199
+ first_public_child = create(:alchemy_page, :public, name: "First public child", language: language, parent_id: language_root.id)
1082
1200
  expect(language_root.first_public_child).to eq(first_public_child)
1083
1201
  end
1084
1202
 
@@ -1121,7 +1239,7 @@ module Alchemy
1121
1239
 
1122
1240
  context 'if page is not folded' do
1123
1241
  it "should return false" do
1124
- expect(page.folded?(101093)).to eq(false)
1242
+ expect(page.folded?(101_093)).to eq(false)
1125
1243
  end
1126
1244
  end
1127
1245
  end
@@ -1137,33 +1255,33 @@ module Alchemy
1137
1255
  end
1138
1256
  end
1139
1257
 
1140
- describe '#layout_description' do
1258
+ describe '#definition' do
1141
1259
  context 'if the page layout could not be found in the definition file' do
1142
- let(:page) { build_stubbed(:page, page_layout: 'notexisting') }
1260
+ let(:page) { build_stubbed(:alchemy_page, page_layout: 'notexisting') }
1143
1261
 
1144
1262
  it "it loggs a warning." do
1145
1263
  expect(Alchemy::Logger).to receive(:warn)
1146
- page.layout_description
1264
+ page.definition
1147
1265
  end
1148
1266
 
1149
1267
  it "it returns empty hash." do
1150
- expect(page.layout_description).to eq({})
1268
+ expect(page.definition).to eq({})
1151
1269
  end
1152
1270
  end
1153
1271
 
1154
1272
  context "for a language root page" do
1155
- it "it returns the page layout description as hash." do
1156
- expect(language_root.layout_description['name']).to eq('index')
1273
+ it "it returns the page layout definition as hash." do
1274
+ expect(language_root.definition['name']).to eq('index')
1157
1275
  end
1158
1276
 
1159
1277
  it "it returns an empty hash for root page." do
1160
- expect(rootpage.layout_description).to eq({})
1278
+ expect(rootpage.definition).to eq({})
1161
1279
  end
1162
1280
  end
1163
1281
  end
1164
1282
 
1165
1283
  describe '#lock_to!' do
1166
- let(:page) { create(:page) }
1284
+ let(:page) { create(:alchemy_page) }
1167
1285
  let(:user) { mock_model('DummyUser') }
1168
1286
 
1169
1287
  it "should set locked to true" do
@@ -1184,8 +1302,8 @@ module Alchemy
1184
1302
  end
1185
1303
 
1186
1304
  describe '#copy_and_paste' do
1187
- let(:source) { FactoryGirl.build_stubbed(:page) }
1188
- let(:new_parent) { FactoryGirl.build_stubbed(:page) }
1305
+ let(:source) { build_stubbed(:alchemy_page) }
1306
+ let(:new_parent) { build_stubbed(:alchemy_page) }
1189
1307
  let(:page_name) { "Pagename (pasted)" }
1190
1308
  let(:copied_page) { mock_model('Page') }
1191
1309
 
@@ -1217,10 +1335,10 @@ module Alchemy
1217
1335
  end
1218
1336
 
1219
1337
  context 'previous and next.' do
1220
- let(:center_page) { FactoryGirl.create(:public_page, name: 'Center Page') }
1221
- let(:next_page) { FactoryGirl.create(:public_page, name: 'Next Page') }
1222
- let(:non_public_page) { FactoryGirl.create(:page, name: 'Not public Page') }
1223
- let(:restricted_page) { FactoryGirl.create(:restricted_page, public: true) }
1338
+ let(:center_page) { create(:alchemy_page, :public, name: 'Center Page') }
1339
+ let(:next_page) { create(:alchemy_page, :public, name: 'Next Page') }
1340
+ let(:non_public_page) { create(:alchemy_page, name: 'Not public Page') }
1341
+ let(:restricted_page) { create(:alchemy_page, :restricted, public: true) }
1224
1342
 
1225
1343
  before do
1226
1344
  public_page
@@ -1285,8 +1403,8 @@ module Alchemy
1285
1403
  end
1286
1404
 
1287
1405
  describe '#publish!' do
1288
- let(:page) { FactoryGirl.build_stubbed(:page, public: false) }
1289
- let(:current_time) { Time.now }
1406
+ let(:page) { build_stubbed(:alchemy_page, public: false) }
1407
+ let(:current_time) { Time.current }
1290
1408
 
1291
1409
  before do
1292
1410
  current_time
@@ -1342,7 +1460,7 @@ module Alchemy
1342
1460
  describe '#taggable?' do
1343
1461
  context "definition has 'taggable' key with true value" do
1344
1462
  it "should return true" do
1345
- page = FactoryGirl.build(:page)
1463
+ page = build(:alchemy_page)
1346
1464
  allow(page).to receive(:definition).and_return({'name' => 'standard', 'taggable' => true})
1347
1465
  expect(page.taggable?).to be_truthy
1348
1466
  end
@@ -1350,7 +1468,7 @@ module Alchemy
1350
1468
 
1351
1469
  context "definition has 'taggable' key with foo value" do
1352
1470
  it "should return false" do
1353
- page = FactoryGirl.build(:page)
1471
+ page = build(:alchemy_page)
1354
1472
  allow(page).to receive(:definition).and_return({'name' => 'standard', 'taggable' => 'foo'})
1355
1473
  expect(page.taggable?).to be_falsey
1356
1474
  end
@@ -1358,7 +1476,7 @@ module Alchemy
1358
1476
 
1359
1477
  context "definition has no 'taggable' key" do
1360
1478
  it "should return false" do
1361
- page = FactoryGirl.build(:page)
1479
+ page = build(:alchemy_page)
1362
1480
  allow(page).to receive(:definition).and_return({'name' => 'standard'})
1363
1481
  expect(page.taggable?).to be_falsey
1364
1482
  end
@@ -1366,7 +1484,7 @@ module Alchemy
1366
1484
  end
1367
1485
 
1368
1486
  describe '#unlock!' do
1369
- let(:page) { FactoryGirl.create(:page, locked: true, locked_by: 1) }
1487
+ let(:page) { create(:alchemy_page, locked: true, locked_by: 1) }
1370
1488
 
1371
1489
  before do
1372
1490
  allow(page).to receive(:save).and_return(true)
@@ -1396,12 +1514,12 @@ module Alchemy
1396
1514
  end
1397
1515
 
1398
1516
  context 'urlname updating' do
1399
- let(:parentparent) { FactoryGirl.create(:page, name: 'parentparent', visible: true) }
1400
- let(:parent) { FactoryGirl.create(:page, parent_id: parentparent.id, name: 'parent', visible: true) }
1401
- let(:page) { FactoryGirl.create(:page, parent_id: parent.id, name: 'page', visible: true) }
1402
- let(:invisible) { FactoryGirl.create(:page, parent_id: page.id, name: 'invisible', visible: false) }
1403
- let(:contact) { FactoryGirl.create(:page, parent_id: invisible.id, name: 'contact', visible: true) }
1404
- let(:external) { FactoryGirl.create(:page, parent_id: parent.id, name: 'external', page_layout: 'external', urlname: 'http://google.com') }
1517
+ let(:parentparent) { create(:alchemy_page, name: 'parentparent', visible: true) }
1518
+ let(:parent) { create(:alchemy_page, parent_id: parentparent.id, name: 'parent', visible: true) }
1519
+ let(:page) { create(:alchemy_page, parent_id: parent.id, name: 'page', visible: true) }
1520
+ let(:invisible) { create(:alchemy_page, parent_id: page.id, name: 'invisible', visible: false) }
1521
+ let(:contact) { create(:alchemy_page, parent_id: invisible.id, name: 'contact', visible: true) }
1522
+ let(:external) { create(:alchemy_page, parent_id: parent.id, name: 'external', page_layout: 'external', urlname: 'http://google.com') }
1405
1523
  let(:language_root) { parentparent.parent }
1406
1524
 
1407
1525
  context "with activated url_nesting" do
@@ -1485,16 +1603,14 @@ module Alchemy
1485
1603
  end
1486
1604
 
1487
1605
  describe "#update_node!" do
1488
-
1489
1606
  let(:original_url) { "sample-url" }
1490
- let(:page) { FactoryGirl.create(:page, language: language, parent_id: language_root.id, urlname: original_url, restricted: false) }
1607
+ let(:page) { create(:alchemy_page, language: language, parent_id: language_root.id, urlname: original_url, restricted: false) }
1491
1608
  let(:node) { TreeNode.new(10, 11, 12, 13, "another-url", true) }
1492
1609
 
1493
1610
  context "when nesting is enabled" do
1494
1611
  before { allow(Alchemy::Config).to receive(:get).with(:url_nesting) { true } }
1495
1612
 
1496
1613
  context "when page is not external" do
1497
-
1498
1614
  before do
1499
1615
  expect(page).to receive(:redirects_to_external?).and_return(false)
1500
1616
  end
@@ -1609,9 +1725,45 @@ module Alchemy
1609
1725
  end
1610
1726
  end
1611
1727
 
1728
+ describe '#cache_page?' do
1729
+ let(:page) { Page.new(page_layout: "news") }
1730
+ subject { page.cache_page? }
1731
+
1732
+ before { Rails.application.config.action_controller.perform_caching = true }
1733
+ after { Rails.application.config.action_controller.perform_caching = false }
1734
+
1735
+ it 'returns true when everthing is alright' do
1736
+ expect(subject).to be true
1737
+ end
1738
+
1739
+ it 'returns false when the Rails app does not perform caching' do
1740
+ Rails.application.config.action_controller.perform_caching = false
1741
+ expect(subject).to be false
1742
+ end
1743
+
1744
+ it 'returns false when caching is deactivated in the Alchemy config' do
1745
+ allow(Alchemy::Config).to receive(:get).with(:cache_pages).and_return(false)
1746
+ expect(subject).to be false
1747
+ end
1748
+
1749
+ it 'returns false when the page layout is set to cache = false' do
1750
+ page_layout = PageLayout.get('news')
1751
+ page_layout['cache'] = false
1752
+ allow(PageLayout).to receive(:get).with('news').and_return(page_layout)
1753
+ expect(subject).to be false
1754
+ end
1755
+
1756
+ it 'returns false when the page layout is set to searchresults = true' do
1757
+ page_layout = PageLayout.get('news')
1758
+ page_layout['searchresults'] = true
1759
+ allow(PageLayout).to receive(:get).with('news').and_return(page_layout)
1760
+ expect(subject).to be false
1761
+ end
1762
+ end
1763
+
1612
1764
  describe '#slug' do
1613
1765
  context "with parents path saved in urlname" do
1614
- let(:page) { FactoryGirl.build(:page, urlname: 'root/parent/my-name')}
1766
+ let(:page) { build(:alchemy_page, urlname: 'root/parent/my-name') }
1615
1767
 
1616
1768
  it "should return the last part of the urlname" do
1617
1769
  expect(page.slug).to eq('my-name')
@@ -1619,7 +1771,7 @@ module Alchemy
1619
1771
  end
1620
1772
 
1621
1773
  context "with single urlname" do
1622
- let(:page) { FactoryGirl.build(:page, urlname: 'my-name')}
1774
+ let(:page) { build(:alchemy_page, urlname: 'my-name') }
1623
1775
 
1624
1776
  it "should return the last part of the urlname" do
1625
1777
  expect(page.slug).to eq('my-name')
@@ -1627,7 +1779,7 @@ module Alchemy
1627
1779
  end
1628
1780
 
1629
1781
  context "with nil as urlname" do
1630
- let(:page) { FactoryGirl.build(:page, urlname: nil)}
1782
+ let(:page) { build(:alchemy_page, urlname: nil) }
1631
1783
 
1632
1784
  it "should return nil" do
1633
1785
  expect(page.slug).to be_nil
@@ -1636,10 +1788,10 @@ module Alchemy
1636
1788
  end
1637
1789
 
1638
1790
  describe '#external_urlname' do
1639
- let(:external_page) { build(:page, page_layout: 'external') }
1791
+ let(:external_page) { build(:alchemy_page, page_layout: 'external') }
1640
1792
 
1641
1793
  context 'with missing protocol' do
1642
- before { external_page.urlname = 'google.com'}
1794
+ before { external_page.urlname = 'google.com' }
1643
1795
 
1644
1796
  it "returns an urlname prefixed with http://" do
1645
1797
  expect(external_page.external_urlname).to eq 'http://google.com'
@@ -1647,7 +1799,7 @@ module Alchemy
1647
1799
  end
1648
1800
 
1649
1801
  context 'with protocol present' do
1650
- before { external_page.urlname = 'ftp://google.com'}
1802
+ before { external_page.urlname = 'ftp://google.com' }
1651
1803
 
1652
1804
  it "returns the urlname" do
1653
1805
  expect(external_page.external_urlname).to eq 'ftp://google.com'
@@ -1655,7 +1807,7 @@ module Alchemy
1655
1807
  end
1656
1808
 
1657
1809
  context 'beginngin with a slash' do
1658
- before { external_page.urlname = '/internal-url'}
1810
+ before { external_page.urlname = '/internal-url' }
1659
1811
 
1660
1812
  it "returns the urlname" do
1661
1813
  expect(external_page.external_urlname).to eq '/internal-url'
@@ -1664,7 +1816,7 @@ module Alchemy
1664
1816
  end
1665
1817
 
1666
1818
  context 'page status methods' do
1667
- let(:page) { FactoryGirl.build(:page, public: true, visible: true, restricted: false, locked: false)}
1819
+ let(:page) { build(:alchemy_page, public: true, visible: true, restricted: false, locked: false) }
1668
1820
 
1669
1821
  describe '#status' do
1670
1822
  it "returns a combined status hash" do
@@ -1849,10 +2001,10 @@ module Alchemy
1849
2001
  describe '#controller_and_action' do
1850
2002
  let(:page) { Page.new }
1851
2003
 
1852
- context 'if the page has a custom controller defined in its description' do
2004
+ context 'if the page has a custom controller defined in its definition' do
1853
2005
  before do
1854
2006
  allow(page).to receive(:has_controller?).and_return(true)
1855
- allow(page).to receive(:layout_description).and_return({'controller' => 'comments', 'action' => 'index'})
2007
+ allow(page).to receive(:definition).and_return({'controller' => 'comments', 'action' => 'index'})
1856
2008
  end
1857
2009
  it "should return a Hash with controller and action key-value pairs" do
1858
2010
  expect(page.controller_and_action).to eq({controller: '/comments', action: 'index'})
@@ -1874,8 +2026,8 @@ module Alchemy
1874
2026
 
1875
2027
  describe '#published_at' do
1876
2028
  context 'with published_at date set' do
1877
- let(:published_at) { Time.now }
1878
- let(:page) { build_stubbed(:page, published_at: published_at) }
2029
+ let(:published_at) { Time.current }
2030
+ let(:page) { build_stubbed(:alchemy_page, published_at: published_at) }
1879
2031
 
1880
2032
  it "returns the published_at value from database" do
1881
2033
  expect(page.published_at).to eq(published_at)
@@ -1883,8 +2035,8 @@ module Alchemy
1883
2035
  end
1884
2036
 
1885
2037
  context 'with published_at is nil' do
1886
- let(:updated_at) { Time.now }
1887
- let(:page) { build_stubbed(:page, published_at: nil, updated_at: updated_at) }
2038
+ let(:updated_at) { Time.current }
2039
+ let(:page) { build_stubbed(:alchemy_page, published_at: nil, updated_at: updated_at) }
1888
2040
 
1889
2041
  it "returns the updated_at value" do
1890
2042
  expect(page.published_at).to eq(updated_at)
@@ -1892,5 +2044,65 @@ module Alchemy
1892
2044
  end
1893
2045
  end
1894
2046
 
2047
+ describe "#richtext_contents_ids" do
2048
+ let!(:page) { create(:alchemy_page) }
2049
+
2050
+ let!(:expanded_element) do
2051
+ create :alchemy_element,
2052
+ name: 'article',
2053
+ page: page,
2054
+ folded: false,
2055
+ create_contents_after_create: true
2056
+ end
2057
+
2058
+ let!(:folded_element) do
2059
+ create :alchemy_element,
2060
+ name: 'article',
2061
+ page: page,
2062
+ folded: true,
2063
+ create_contents_after_create: true
2064
+ end
2065
+
2066
+ subject(:richtext_contents_ids) { page.richtext_contents_ids }
2067
+
2068
+ it 'returns content ids for all expanded elements that have tinymce enabled' do
2069
+ expanded_rtf_contents = expanded_element.contents.essence_richtexts
2070
+ expect(richtext_contents_ids).to eq(expanded_rtf_contents.pluck(:id))
2071
+ folded_rtf_content = folded_element.contents.essence_richtexts.first
2072
+ expect(richtext_contents_ids).to_not include(folded_rtf_content.id)
2073
+ end
2074
+
2075
+ context 'with nested elements' do
2076
+ let!(:nested_expanded_element) do
2077
+ create :alchemy_element,
2078
+ name: 'article',
2079
+ page: page,
2080
+ parent_element: expanded_element,
2081
+ folded: false,
2082
+ create_contents_after_create: true
2083
+ end
2084
+
2085
+ let!(:nested_folded_element) do
2086
+ create :alchemy_element,
2087
+ name: 'article',
2088
+ page: page,
2089
+ parent_element: folded_element,
2090
+ folded: true,
2091
+ create_contents_after_create: true
2092
+ end
2093
+
2094
+ it 'returns content ids for all expanded nested elements that have tinymce enabled' do
2095
+ expanded_rtf_contents = expanded_element.contents.essence_richtexts
2096
+ nested_expanded_rtf_contents = nested_expanded_element.contents.essence_richtexts
2097
+ rtf_content_ids = expanded_rtf_contents.pluck(:id) +
2098
+ nested_expanded_rtf_contents.pluck(:id)
2099
+ expect(richtext_contents_ids.sort).to eq(rtf_content_ids)
2100
+
2101
+ nested_folded_rtf_content = nested_folded_element.contents.essence_richtexts.first
2102
+
2103
+ expect(richtext_contents_ids).to_not include(nested_folded_rtf_content.id)
2104
+ end
2105
+ end
2106
+ end
1895
2107
  end
1896
2108
  end