alchemy_cms 3.2.1 → 3.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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