alchemy_cms 3.2.1 → 3.3.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (556) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +28 -0
  3. data/.gitignore +2 -2
  4. data/.travis.yml +11 -3
  5. data/CHANGELOG.md +100 -0
  6. data/CONTRIBUTING.md +1 -1
  7. data/Gemfile +12 -1
  8. data/README.md +25 -7
  9. data/Rakefile +1 -3
  10. data/alchemy_cms.gemspec +7 -15
  11. data/app/assets/fonts/alchemy/icons.eot +0 -0
  12. data/app/assets/fonts/alchemy/icons.svg +28 -66
  13. data/app/assets/fonts/alchemy/icons.ttf +0 -0
  14. data/app/assets/fonts/alchemy/icons.woff +0 -0
  15. data/app/assets/images/alchemy/icons.png +0 -0
  16. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +10 -3
  17. data/app/assets/javascripts/alchemy/alchemy.buttons.js.coffee +15 -6
  18. data/app/assets/javascripts/alchemy/alchemy.char_counter.js.coffee +1 -1
  19. data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +1 -1
  20. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +10 -4
  21. data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +16 -22
  22. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +69 -32
  23. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +147 -83
  24. data/app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee +14 -14
  25. data/app/assets/javascripts/alchemy/alchemy.hotkeys.js.coffee +1 -1
  26. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +1 -1
  27. data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +55 -0
  28. data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +8 -1
  29. data/app/assets/javascripts/alchemy/alchemy.js +3 -1
  30. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +36 -31
  31. data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +35 -29
  32. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +51 -5
  33. data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +26 -10
  34. data/app/assets/javascripts/alchemy/{alchemy.windows.js.coffee → alchemy.trash_window.js.coffee} +1 -13
  35. data/app/assets/javascripts/alchemy/alchemy.uploader.js.coffee +15 -17
  36. data/app/assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js +3 -3
  37. data/app/assets/stylesheets/alchemy/_extends.scss +1 -1
  38. data/app/assets/stylesheets/alchemy/_mixins.scss +27 -0
  39. data/app/assets/stylesheets/alchemy/_variables.scss +1 -0
  40. data/app/assets/stylesheets/alchemy/admin.scss +1 -0
  41. data/app/assets/stylesheets/alchemy/archive.scss +0 -57
  42. data/app/assets/stylesheets/alchemy/base.scss +1 -18
  43. data/app/assets/stylesheets/alchemy/buttons.scss +30 -25
  44. data/app/assets/stylesheets/alchemy/dialogs.scss +25 -9
  45. data/app/assets/stylesheets/alchemy/elements.scss +182 -126
  46. data/app/assets/stylesheets/alchemy/form_fields.scss +14 -8
  47. data/app/assets/stylesheets/alchemy/forms.scss +10 -1
  48. data/app/assets/stylesheets/alchemy/frame.scss +3 -10
  49. data/app/assets/stylesheets/alchemy/icon-font.scss +13 -6
  50. data/app/assets/stylesheets/alchemy/icons.scss +16 -0
  51. data/app/assets/stylesheets/alchemy/image_library.scss +269 -0
  52. data/app/assets/stylesheets/alchemy/selects.scss +1 -0
  53. data/app/assets/stylesheets/alchemy/sitemap.scss +12 -1
  54. data/app/assets/stylesheets/alchemy/toolbar.scss +2 -2
  55. data/app/assets/stylesheets/alchemy/upload.scss +97 -87
  56. data/app/assets/stylesheets/alchemy/welcome.sass +49 -0
  57. data/app/controllers/alchemy/admin/attachments_controller.rb +21 -29
  58. data/app/controllers/alchemy/admin/base_controller.rb +23 -4
  59. data/app/controllers/alchemy/admin/clipboard_controller.rb +0 -1
  60. data/app/controllers/alchemy/admin/contents_controller.rb +2 -4
  61. data/app/controllers/alchemy/admin/dashboard_controller.rb +4 -4
  62. data/app/controllers/alchemy/admin/elements_controller.rb +20 -11
  63. data/app/controllers/alchemy/admin/essence_files_controller.rb +2 -2
  64. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +10 -9
  65. data/app/controllers/alchemy/admin/languages_controller.rb +0 -1
  66. data/app/controllers/alchemy/admin/layoutpages_controller.rb +0 -2
  67. data/app/controllers/alchemy/admin/legacy_page_urls_controller.rb +0 -1
  68. data/app/controllers/alchemy/admin/pages_controller.rb +46 -29
  69. data/app/controllers/alchemy/admin/pictures_controller.rb +44 -55
  70. data/app/controllers/alchemy/admin/resources_controller.rb +8 -75
  71. data/app/controllers/alchemy/admin/tags_controller.rb +10 -8
  72. data/app/controllers/alchemy/admin/trash_controller.rb +0 -6
  73. data/app/controllers/alchemy/api/contents_controller.rb +0 -1
  74. data/app/controllers/alchemy/api/elements_controller.rb +0 -1
  75. data/app/controllers/alchemy/api/pages_controller.rb +4 -1
  76. data/app/controllers/alchemy/attachments_controller.rb +4 -5
  77. data/app/controllers/alchemy/base_controller.rb +6 -5
  78. data/app/controllers/alchemy/elements_controller.rb +1 -1
  79. data/app/controllers/alchemy/messages_controller.rb +9 -4
  80. data/app/controllers/alchemy/pages_controller.rb +133 -137
  81. data/app/controllers/alchemy/pictures_controller.rb +12 -10
  82. data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +41 -0
  83. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +56 -0
  84. data/app/controllers/concerns/alchemy/locale_redirects.rb +38 -0
  85. data/app/controllers/concerns/alchemy/page_redirects.rb +80 -0
  86. data/app/controllers/concerns/alchemy/site_redirects.rb +22 -0
  87. data/app/helpers/alchemy/admin/attachments_helper.rb +1 -2
  88. data/app/helpers/alchemy/admin/base_helper.rb +36 -62
  89. data/app/helpers/alchemy/admin/contents_helper.rb +6 -80
  90. data/app/helpers/alchemy/admin/elements_helper.rb +36 -15
  91. data/app/helpers/alchemy/admin/essences_helper.rb +15 -8
  92. data/app/helpers/alchemy/admin/form_helper.rb +6 -10
  93. data/app/helpers/alchemy/admin/navigation_helper.rb +4 -7
  94. data/app/helpers/alchemy/admin/pages_helper.rb +14 -35
  95. data/app/helpers/alchemy/admin/pictures_helper.rb +12 -14
  96. data/app/helpers/alchemy/admin/tags_helper.rb +5 -7
  97. data/app/helpers/alchemy/base_helper.rb +9 -17
  98. data/app/helpers/alchemy/elements_block_helper.rb +5 -13
  99. data/app/helpers/alchemy/elements_helper.rb +6 -6
  100. data/app/helpers/alchemy/essences_helper.rb +3 -16
  101. data/app/helpers/alchemy/pages_helper.rb +32 -25
  102. data/app/helpers/alchemy/url_helper.rb +14 -16
  103. data/app/mailers/alchemy/messages.rb +0 -2
  104. data/app/models/alchemy.rb +0 -2
  105. data/app/models/alchemy/attachment.rb +45 -56
  106. data/app/models/alchemy/cell.rb +7 -8
  107. data/app/models/alchemy/content.rb +39 -24
  108. data/app/models/alchemy/content/factory.rb +27 -44
  109. data/app/models/alchemy/element.rb +101 -267
  110. data/app/models/alchemy/element/definitions.rb +9 -8
  111. data/app/models/alchemy/element/element_contents.rb +150 -0
  112. data/app/models/alchemy/element/element_essences.rb +109 -0
  113. data/app/models/alchemy/element/presenters.rb +18 -7
  114. data/app/models/alchemy/essence_date.rb +1 -2
  115. data/app/models/alchemy/essence_file.rb +10 -6
  116. data/app/models/alchemy/essence_html.rb +0 -1
  117. data/app/models/alchemy/essence_picture.rb +12 -4
  118. data/app/models/alchemy/essence_richtext.rb +6 -3
  119. data/app/models/alchemy/language.rb +48 -21
  120. data/app/models/alchemy/language/code.rb +1 -4
  121. data/app/models/alchemy/page.rb +33 -35
  122. data/app/models/alchemy/page/page_cells.rb +6 -10
  123. data/app/models/alchemy/page/page_elements.rb +130 -100
  124. data/app/models/alchemy/page/page_naming.rb +2 -3
  125. data/app/models/alchemy/page/page_natures.rb +50 -16
  126. data/app/models/alchemy/page/page_scopes.rb +7 -7
  127. data/app/models/alchemy/page/page_users.rb +3 -3
  128. data/app/models/alchemy/picture.rb +48 -33
  129. data/app/models/alchemy/picture/transformations.rb +8 -9
  130. data/app/models/alchemy/site.rb +19 -17
  131. data/app/models/alchemy/site/layout.rb +9 -9
  132. data/app/models/alchemy/tag.rb +0 -2
  133. data/app/models/alchemy/tree_node.rb +5 -4
  134. data/app/serializers/alchemy/attachment_serializer.rb +0 -1
  135. data/app/serializers/alchemy/base_serializer.rb +30 -0
  136. data/app/serializers/alchemy/cell_serializer.rb +0 -1
  137. data/app/serializers/alchemy/essence_boolean_serializer.rb +0 -1
  138. data/app/serializers/alchemy/essence_date_serializer.rb +0 -1
  139. data/app/serializers/alchemy/essence_file_serializer.rb +0 -1
  140. data/app/serializers/alchemy/essence_html_serializer.rb +0 -1
  141. data/app/serializers/alchemy/essence_link_serializer.rb +0 -1
  142. data/app/serializers/alchemy/essence_picture_serializer.rb +0 -1
  143. data/app/serializers/alchemy/essence_richtext_serializer.rb +0 -1
  144. data/app/serializers/alchemy/essence_select_serializer.rb +0 -1
  145. data/app/serializers/alchemy/essence_text_serializer.rb +0 -1
  146. data/app/serializers/alchemy/legacy_element_serializer.rb +0 -1
  147. data/app/serializers/alchemy/page_serializer.rb +0 -1
  148. data/app/serializers/alchemy/page_tree_serializer.rb +90 -0
  149. data/app/serializers/alchemy/picture_serializer.rb +0 -1
  150. data/app/views/alchemy/_menubar.html.erb +3 -3
  151. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +11 -16
  152. data/app/views/alchemy/admin/attachments/_attachment.html.erb +9 -9
  153. data/app/views/alchemy/admin/attachments/_files_list.html.erb +7 -15
  154. data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
  155. data/app/views/alchemy/admin/attachments/_tag_list.html.erb +2 -2
  156. data/app/views/alchemy/admin/attachments/edit.html.erb +3 -3
  157. data/app/views/alchemy/admin/attachments/index.html.erb +10 -17
  158. data/app/views/alchemy/admin/clipboard/clear.js.erb +1 -1
  159. data/app/views/alchemy/admin/clipboard/index.html.erb +3 -3
  160. data/app/views/alchemy/admin/clipboard/insert.js.erb +3 -3
  161. data/app/views/alchemy/admin/clipboard/remove.js.erb +2 -2
  162. data/app/views/alchemy/admin/contents/_missing.html.erb +5 -7
  163. data/app/views/alchemy/admin/contents/create.js.erb +1 -1
  164. data/app/views/alchemy/admin/contents/new.html.erb +2 -2
  165. data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +6 -6
  166. data/app/views/alchemy/admin/dashboard/_recent_pages.html.erb +2 -2
  167. data/app/views/alchemy/admin/dashboard/_users.html.erb +2 -2
  168. data/app/views/alchemy/admin/dashboard/help.html.erb +15 -15
  169. data/app/views/alchemy/admin/dashboard/index.html.erb +6 -6
  170. data/app/views/alchemy/admin/dashboard/info.html.erb +5 -5
  171. data/app/views/alchemy/admin/elements/_add_picture.html.erb +1 -1
  172. data/app/views/alchemy/admin/elements/_element.html.erb +52 -18
  173. data/app/views/alchemy/admin/elements/_element_footer.html.erb +11 -0
  174. data/app/views/alchemy/admin/elements/{_element_head.html.erb → _element_header.html.erb} +8 -8
  175. data/app/views/alchemy/admin/elements/_element_toolbar.html.erb +49 -0
  176. data/app/views/alchemy/admin/elements/_new_element_form.html.erb +7 -6
  177. data/app/views/alchemy/admin/elements/_picture_gallery_editor.html.erb +1 -1
  178. data/app/views/alchemy/admin/elements/_refresh_editor.js.erb +1 -1
  179. data/app/views/alchemy/admin/elements/create.js.erb +13 -8
  180. data/app/views/alchemy/admin/elements/fold.js.erb +12 -7
  181. data/app/views/alchemy/admin/elements/index.html.erb +12 -8
  182. data/app/views/alchemy/admin/elements/list.html.erb +3 -3
  183. data/app/views/alchemy/admin/elements/new.html.erb +4 -4
  184. data/app/views/alchemy/admin/elements/order.js.erb +3 -4
  185. data/app/views/alchemy/admin/elements/publish.js.erb +15 -0
  186. data/app/views/alchemy/admin/elements/trash.js.erb +3 -3
  187. data/app/views/alchemy/admin/elements/update.js.erb +7 -8
  188. data/app/views/alchemy/admin/essence_files/edit.html.erb +16 -13
  189. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +3 -3
  190. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +8 -8
  191. data/app/views/alchemy/admin/languages/_form.html.erb +12 -3
  192. data/app/views/alchemy/admin/languages/_language.html.erb +8 -2
  193. data/app/views/alchemy/admin/languages/_table.html.erb +11 -5
  194. data/app/views/alchemy/admin/languages/index.html.erb +1 -1
  195. data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +8 -8
  196. data/app/views/alchemy/admin/layoutpages/edit.html.erb +2 -2
  197. data/app/views/alchemy/admin/layoutpages/index.html.erb +6 -13
  198. data/app/views/alchemy/admin/leave.html.erb +5 -5
  199. data/app/views/alchemy/admin/legacy_page_urls/_form.html.erb +1 -1
  200. data/app/views/alchemy/admin/legacy_page_urls/_legacy_page_url.html.erb +4 -4
  201. data/app/views/alchemy/admin/legacy_page_urls/_new.html.erb +1 -1
  202. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +9 -9
  203. data/app/views/alchemy/admin/pages/_external_link.html.erb +6 -6
  204. data/app/views/alchemy/admin/pages/_file_link.html.erb +6 -6
  205. data/app/views/alchemy/admin/pages/_form.html.erb +6 -6
  206. data/app/views/alchemy/admin/pages/_internal_link.html.erb +9 -11
  207. data/app/views/alchemy/admin/pages/_legacy_urls.html.erb +3 -3
  208. data/app/views/alchemy/admin/pages/_locked_page.html.erb +4 -4
  209. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +2 -2
  210. data/app/views/alchemy/admin/pages/_page.html.erb +95 -80
  211. data/app/views/alchemy/admin/pages/_page_for_links.html.erb +22 -22
  212. data/app/views/alchemy/admin/pages/_page_infos.html.erb +12 -0
  213. data/app/views/alchemy/admin/pages/_page_status.html.erb +7 -9
  214. data/app/views/alchemy/admin/pages/_sitemap.html.erb +35 -6
  215. data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +0 -3
  216. data/app/views/alchemy/admin/pages/configure.html.erb +1 -1
  217. data/app/views/alchemy/admin/pages/configure_external.html.erb +4 -4
  218. data/app/views/alchemy/admin/pages/edit.html.erb +39 -44
  219. data/app/views/alchemy/admin/pages/flush.js.erb +1 -1
  220. data/app/views/alchemy/admin/pages/fold.js.erb +2 -3
  221. data/app/views/alchemy/admin/pages/index.html.erb +15 -22
  222. data/app/views/alchemy/admin/pages/info.html.erb +8 -8
  223. data/app/views/alchemy/admin/pages/link.html.erb +3 -3
  224. data/app/views/alchemy/admin/pages/locked.html.erb +1 -1
  225. data/app/views/alchemy/admin/pages/new.html.erb +4 -4
  226. data/app/views/alchemy/admin/pages/sort.js.erb +1 -2
  227. data/app/views/alchemy/admin/pages/unlock.js.erb +1 -1
  228. data/app/views/alchemy/admin/pages/update.js.erb +3 -3
  229. data/app/views/alchemy/admin/partials/_autocomplete_tag_list.html.erb +1 -1
  230. data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +1 -1
  231. data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +1 -1
  232. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +9 -15
  233. data/app/views/alchemy/admin/partials/_search_form.html.erb +14 -13
  234. data/app/views/alchemy/admin/partials/_sub_navigation.html.erb +1 -1
  235. data/app/views/alchemy/admin/pictures/_archive.html.erb +14 -14
  236. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +30 -36
  237. data/app/views/alchemy/admin/pictures/_filter_bar.html.erb +5 -5
  238. data/app/views/alchemy/admin/pictures/{edit.html.erb → _form.html.erb} +7 -6
  239. data/app/views/alchemy/admin/pictures/_infos.html.erb +50 -0
  240. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
  241. data/app/views/alchemy/admin/pictures/_picture.html.erb +17 -51
  242. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -1
  243. data/app/views/alchemy/admin/pictures/_tag_list.html.erb +2 -2
  244. data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +6 -6
  245. data/app/views/alchemy/admin/pictures/index.html.erb +28 -36
  246. data/app/views/alchemy/admin/pictures/show.html.erb +46 -9
  247. data/app/views/alchemy/admin/pictures/update.js.erb +6 -0
  248. data/app/views/alchemy/admin/resources/_form.html.erb +3 -3
  249. data/app/views/alchemy/admin/resources/_resource.html.erb +4 -4
  250. data/app/views/alchemy/admin/resources/_table.html.erb +5 -6
  251. data/app/views/alchemy/admin/resources/index.csv.erb +12 -10
  252. data/app/views/alchemy/admin/resources/index.html.erb +4 -4
  253. data/app/views/alchemy/admin/sites/index.html.erb +1 -1
  254. data/app/views/alchemy/admin/tags/_tag.html.erb +4 -4
  255. data/app/views/alchemy/admin/tags/edit.html.erb +5 -5
  256. data/app/views/alchemy/admin/tags/index.html.erb +8 -8
  257. data/app/views/alchemy/admin/tags/new.html.erb +2 -2
  258. data/app/views/alchemy/admin/trash/clear.js.erb +1 -1
  259. data/app/views/alchemy/admin/trash/index.html.erb +8 -6
  260. data/app/views/alchemy/admin/uploader/_button.html.erb +39 -0
  261. data/app/views/alchemy/admin/uploader/_setup.html.erb +13 -0
  262. data/app/views/alchemy/base/500.html.erb +4 -4
  263. data/app/views/alchemy/elements/_editor_not_found.html.erb +1 -1
  264. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +3 -4
  265. data/app/views/alchemy/essences/_essence_boolean_view.html.erb +1 -1
  266. data/app/views/alchemy/essences/_essence_date_editor.html.erb +2 -6
  267. data/app/views/alchemy/essences/_essence_date_view.html.erb +1 -1
  268. data/app/views/alchemy/essences/_essence_file_editor.html.erb +9 -11
  269. data/app/views/alchemy/essences/_essence_file_view.html.erb +11 -5
  270. data/app/views/alchemy/essences/_essence_html_editor.html.erb +1 -1
  271. data/app/views/alchemy/essences/_essence_link_editor.html.erb +1 -1
  272. data/app/views/alchemy/essences/_essence_link_view.html.erb +1 -1
  273. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +47 -52
  274. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +1 -1
  275. data/app/views/alchemy/essences/_essence_richtext_view.html.erb +1 -1
  276. data/app/views/alchemy/essences/_essence_select_editor.html.erb +23 -13
  277. data/app/views/alchemy/essences/_essence_text_editor.html.erb +1 -1
  278. data/app/views/alchemy/essences/_essence_text_view.html.erb +1 -1
  279. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +29 -36
  280. data/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb +5 -5
  281. data/app/views/alchemy/language_links/_language.html.erb +15 -9
  282. data/app/views/alchemy/messages/contact_form_mail.de.text.erb +1 -1
  283. data/app/views/alchemy/messages/contact_form_mail.en.text.erb +1 -1
  284. data/app/views/alchemy/messages/contact_form_mail.es.text.erb +1 -1
  285. data/app/views/alchemy/navigation/_link.html.erb +0 -1
  286. data/app/views/alchemy/pages/show.rss.builder +6 -4
  287. data/app/views/alchemy/welcome.html.erb +28 -0
  288. data/app/views/layouts/alchemy/admin.html.erb +14 -10
  289. data/bin/alchemy +3 -4
  290. data/bin/rspec +7 -0
  291. data/bin/spring +15 -0
  292. data/config/alchemy/config.yml +16 -17
  293. data/config/initializers/assets.rb +13 -0
  294. data/config/locales/alchemy.de.yml +27 -29
  295. data/config/locales/alchemy.en.yml +23 -29
  296. data/config/locales/alchemy.es.yml +23 -29
  297. data/config/locales/alchemy.fr.yml +19 -28
  298. data/config/locales/alchemy.nl.yml +19 -27
  299. data/config/locales/alchemy.ru.yml +19 -28
  300. data/config/routes.rb +53 -54
  301. data/config/spring.rb +2 -0
  302. data/db/migrate/20130827094554_alchemy_two_point_six.rb +1 -3
  303. data/db/migrate/20150608204610_add_parent_element_id_to_alchemy_elements.rb +6 -0
  304. data/db/migrate/20150729151825_add_link_text_to_alchemy_essence_files.rb +5 -0
  305. data/db/migrate/20150906195818_add_locale_to_alchemy_languages.rb +7 -0
  306. data/lib/alchemy/auth_accessors.rb +1 -1
  307. data/lib/alchemy/cache_digests/template_tracker.rb +7 -13
  308. data/lib/alchemy/config.rb +5 -7
  309. data/lib/alchemy/configuration_methods.rb +11 -1
  310. data/lib/alchemy/controller_actions.rb +9 -12
  311. data/lib/alchemy/engine.rb +11 -28
  312. data/lib/alchemy/errors.rb +0 -1
  313. data/lib/alchemy/essence.rb +20 -20
  314. data/lib/alchemy/filetypes.rb +1 -3
  315. data/lib/alchemy/forms/builder.rb +0 -2
  316. data/lib/alchemy/hints.rb +1 -3
  317. data/lib/alchemy/i18n.rb +81 -53
  318. data/lib/alchemy/kaminari/scoped_pagination_url_helper.rb +0 -2
  319. data/lib/alchemy/locale.rb +0 -1
  320. data/lib/alchemy/logger.rb +1 -3
  321. data/lib/alchemy/modules.rb +3 -3
  322. data/lib/alchemy/mount_point.rb +0 -2
  323. data/lib/alchemy/name_conversions.rb +1 -3
  324. data/lib/alchemy/on_page_layout.rb +37 -23
  325. data/lib/alchemy/on_page_layout/callbacks_runner.rb +34 -0
  326. data/lib/alchemy/page_layout.rb +23 -24
  327. data/lib/alchemy/paths.rb +32 -0
  328. data/lib/alchemy/permissions.rb +20 -20
  329. data/lib/alchemy/picture_attributes.rb +0 -3
  330. data/lib/alchemy/resource.rb +66 -22
  331. data/lib/alchemy/resources_helper.rb +48 -11
  332. data/lib/alchemy/routing_constraints.rb +4 -5
  333. data/lib/alchemy/seeder.rb +1 -4
  334. data/lib/alchemy/shell.rb +12 -14
  335. data/lib/alchemy/tasks/helpers.rb +5 -7
  336. data/lib/alchemy/test_support/essence_shared_examples.rb +24 -24
  337. data/lib/alchemy/test_support/factories.rb +2 -146
  338. data/lib/alchemy/test_support/factories/attachment_factory.rb +9 -0
  339. data/lib/alchemy/test_support/factories/cell_factory.rb +9 -0
  340. data/lib/alchemy/test_support/factories/content_factory.rb +10 -0
  341. data/lib/alchemy/test_support/factories/dummy_user_factory.rb +21 -0
  342. data/lib/alchemy/test_support/factories/element_factory.rb +21 -0
  343. data/lib/alchemy/test_support/factories/essence_file_factory.rb +8 -0
  344. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +8 -0
  345. data/lib/alchemy/test_support/factories/essence_text_factory.rb +7 -0
  346. data/lib/alchemy/test_support/factories/language_factory.rb +28 -0
  347. data/lib/alchemy/test_support/factories/page_factory.rb +45 -0
  348. data/lib/alchemy/test_support/factories/picture_factory.rb +10 -0
  349. data/lib/alchemy/test_support/factories/site_factory.rb +12 -0
  350. data/lib/alchemy/test_support/integration_helpers.rb +0 -3
  351. data/lib/alchemy/tinymce.rb +24 -35
  352. data/lib/alchemy/touching.rb +5 -6
  353. data/lib/alchemy/upgrader.rb +3 -5
  354. data/lib/alchemy/upgrader/tasks/available_contents_upgrader.rb +155 -0
  355. data/lib/alchemy/upgrader/tasks/nestable_elements_migration.rb +71 -0
  356. data/lib/alchemy/upgrader/tasks/three_point_two_task.rb +31 -0
  357. data/lib/alchemy/upgrader/three_point_three.rb +50 -0
  358. data/lib/alchemy/upgrader/three_point_two.rb +3 -32
  359. data/lib/alchemy/upgrader/three_point_zero.rb +0 -1
  360. data/lib/alchemy/version.rb +1 -1
  361. data/lib/rails/generators/alchemy/base.rb +1 -1
  362. data/lib/rails/generators/alchemy/elements/elements_generator.rb +1 -7
  363. data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +5 -7
  364. data/lib/rails/generators/alchemy/elements/templates/editor.html.haml +6 -8
  365. data/lib/rails/generators/alchemy/elements/templates/editor.html.slim +6 -7
  366. data/lib/rails/generators/alchemy/elements/templates/view.html.erb +4 -4
  367. data/lib/rails/generators/alchemy/elements/templates/view.html.haml +3 -3
  368. data/lib/rails/generators/alchemy/elements/templates/view.html.slim +3 -3
  369. data/lib/rails/generators/alchemy/essence/essence_generator.rb +2 -3
  370. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +1 -1
  371. data/lib/rails/generators/alchemy/install/files/alchemy.de.yml +2 -2
  372. data/lib/rails/generators/alchemy/install/files/alchemy.en.yml +2 -2
  373. data/lib/rails/generators/alchemy/install/files/alchemy.es.yml +3 -3
  374. data/lib/rails/generators/alchemy/install/install_generator.rb +0 -1
  375. data/lib/rails/generators/alchemy/install/templates/elements.yml.tt +2 -2
  376. data/lib/rails/generators/alchemy/install/templates/page_layouts.yml.tt +1 -1
  377. data/lib/rails/generators/alchemy/module/module_generator.rb +1 -1
  378. data/lib/rails/templates/alchemy.rb +2 -2
  379. data/lib/tasks/alchemy/convert.rake +4 -8
  380. data/lib/tasks/alchemy/db.rake +2 -3
  381. data/lib/tasks/alchemy/install.rake +3 -4
  382. data/lib/tasks/alchemy/tidy.rake +4 -5
  383. data/lib/tasks/alchemy/upgrade.rake +2 -4
  384. data/spec/controllers/{admin → alchemy/admin}/attachments_controller_spec.rb +26 -44
  385. data/spec/controllers/{admin → alchemy/admin}/base_controller_spec.rb +14 -1
  386. data/spec/controllers/{admin → alchemy/admin}/clipboard_controller_spec.rb +3 -3
  387. data/spec/controllers/{admin → alchemy/admin}/contents_controller_spec.rb +4 -4
  388. data/spec/controllers/{admin → alchemy/admin}/dashboard_controller_spec.rb +11 -6
  389. data/spec/controllers/{admin → alchemy/admin}/elements_controller_spec.rb +54 -31
  390. data/spec/controllers/{admin → alchemy/admin}/essence_files_controller_spec.rb +8 -3
  391. data/spec/controllers/{admin → alchemy/admin}/essence_pictures_controller_spec.rb +3 -3
  392. data/spec/controllers/{admin → alchemy/admin}/languages_controller_spec.rb +13 -1
  393. data/spec/controllers/{admin → alchemy/admin}/layoutpages_controller_spec.rb +0 -6
  394. data/spec/controllers/{admin → alchemy/admin}/pages_controller_spec.rb +103 -35
  395. data/spec/controllers/{admin → alchemy/admin}/pictures_controller_spec.rb +133 -108
  396. data/spec/controllers/alchemy/admin/resources_controller_spec.rb +81 -0
  397. data/spec/controllers/{admin → alchemy/admin}/trash_controller_spec.rb +12 -13
  398. data/spec/controllers/alchemy/api/contents_controller_spec.rb +12 -13
  399. data/spec/controllers/alchemy/api/elements_controller_spec.rb +8 -9
  400. data/spec/controllers/alchemy/api/pages_controller_spec.rb +40 -7
  401. data/spec/controllers/{attachments_controller_spec.rb → alchemy/attachments_controller_spec.rb} +7 -7
  402. data/spec/controllers/alchemy/base_controller_spec.rb +106 -0
  403. data/spec/controllers/{elements_controller_spec.rb → alchemy/elements_controller_spec.rb} +4 -4
  404. data/spec/controllers/{messages_controller_spec.rb → alchemy/messages_controller_spec.rb} +14 -9
  405. data/spec/controllers/alchemy/on_page_layout_mixin_spec.rb +330 -0
  406. data/spec/controllers/{pages_controller_spec.rb → alchemy/pages_controller_spec.rb} +167 -89
  407. data/spec/controllers/{pictures_controller_spec.rb → alchemy/pictures_controller_spec.rb} +42 -20
  408. data/spec/dummy/app/models/dummy_user.rb +4 -0
  409. data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_view.html.erb +31 -0
  410. data/spec/dummy/app/views/alchemy/elements/_article_editor.html.erb +6 -10
  411. data/spec/dummy/app/views/alchemy/elements/_article_view.html.erb +9 -24
  412. data/spec/dummy/app/views/alchemy/elements/_bild_editor.html.erb +3 -0
  413. data/spec/dummy/app/views/alchemy/elements/_bild_view.html.erb +5 -0
  414. data/spec/dummy/app/views/alchemy/elements/_contactform_editor.html.erb +6 -0
  415. data/spec/dummy/app/views/alchemy/elements/_contactform_view.html.erb +16 -0
  416. data/spec/dummy/app/views/alchemy/elements/_download_editor.html.erb +3 -0
  417. data/spec/dummy/app/views/alchemy/elements/_download_view.html.erb +5 -0
  418. data/spec/dummy/app/views/alchemy/elements/_erb_element_editor.html.erb +3 -0
  419. data/spec/dummy/app/views/alchemy/elements/_erb_element_view.html.erb +5 -0
  420. data/spec/dummy/app/views/alchemy/elements/_header_editor.html.erb +3 -0
  421. data/spec/dummy/app/views/alchemy/elements/_header_view.html.erb +5 -0
  422. data/spec/dummy/app/views/alchemy/elements/_news_editor.html.erb +5 -0
  423. data/spec/dummy/app/views/alchemy/elements/_search_editor.html.erb +1 -0
  424. data/spec/dummy/app/views/alchemy/elements/_search_view.html.erb +4 -0
  425. data/spec/dummy/app/views/alchemy/elements/_slide_editor.html.erb +3 -0
  426. data/spec/dummy/app/views/alchemy/elements/_slide_view.html.erb +5 -0
  427. data/spec/dummy/app/views/alchemy/elements/_slider_editor.html.erb +2 -0
  428. data/spec/dummy/app/views/alchemy/elements/_slider_view.html.erb +4 -0
  429. data/spec/dummy/app/views/alchemy/elements/_text_editor.html.erb +3 -0
  430. data/spec/dummy/app/views/alchemy/elements/_text_view.html.erb +5 -0
  431. data/spec/dummy/app/views/alchemy/page_layouts/_standard.html.erb +1 -0
  432. data/spec/dummy/config/alchemy/elements.yml +10 -13
  433. data/spec/dummy/config/alchemy/page_layouts.yml +1 -1
  434. data/spec/dummy/config/initializers/alchemy.rb +1 -0
  435. data/spec/dummy/config/locales/kl.yml +2 -0
  436. data/spec/dummy/db/migrate/20150608204610_add_parent_element_id_to_alchemy_elements.rb +1 -0
  437. data/spec/dummy/db/migrate/20150729151825_add_link_text_to_alchemy_essence_files.rb +1 -0
  438. data/spec/dummy/db/migrate/20150906195818_add_locale_to_alchemy_languages.rb +1 -0
  439. data/spec/dummy/db/schema.rb +10 -6
  440. data/spec/factories.rb +13 -0
  441. data/spec/features/admin/admin_layout_spec.rb +14 -0
  442. data/spec/features/admin/dashboard_spec.rb +1 -2
  443. data/spec/features/admin/edit_elements_feature_spec.rb +36 -0
  444. data/spec/features/admin/language_tree_feature_spec.rb +7 -8
  445. data/spec/features/admin/languages_features_spec.rb +65 -0
  446. data/spec/features/admin/legacy_page_url_management_spec.rb +3 -3
  447. data/spec/features/admin/link_overlay_spec.rb +16 -17
  448. data/spec/features/admin/locale_select_feature_spec.rb +1 -1
  449. data/spec/features/admin/modules_integration_spec.rb +0 -1
  450. data/spec/features/admin/navigation_feature_spec.rb +11 -2
  451. data/spec/features/admin/page_creation_feature_spec.rb +5 -5
  452. data/spec/features/admin/page_editing_feature_spec.rb +6 -6
  453. data/spec/features/admin/picture_library_integration_spec.rb +3 -3
  454. data/spec/features/admin/resources_integration_spec.rb +7 -12
  455. data/spec/features/admin/site_select_feature_spec.rb +1 -2
  456. data/spec/features/admin/tinymce_feature_spec.rb +0 -1
  457. data/spec/features/page_feature_spec.rb +57 -158
  458. data/spec/features/page_redirects_spec.rb +358 -0
  459. data/spec/features/picture_security_spec.rb +1 -7
  460. data/spec/fixtures/animated.gif +0 -0
  461. data/spec/helpers/{admin → alchemy/admin}/attachments_helper_spec.rb +0 -0
  462. data/spec/helpers/{admin → alchemy/admin}/base_helper_spec.rb +39 -29
  463. data/spec/helpers/{admin → alchemy/admin}/contents_helper_spec.rb +4 -23
  464. data/spec/helpers/{admin → alchemy/admin}/elements_helper_spec.rb +141 -5
  465. data/spec/helpers/{admin → alchemy/admin}/essences_helper_spec.rb +69 -8
  466. data/spec/helpers/{admin → alchemy/admin}/navigation_helper_spec.rb +43 -37
  467. data/spec/helpers/{admin → alchemy/admin}/pages_helper_spec.rb +6 -38
  468. data/spec/helpers/{admin → alchemy/admin}/pictures_helper_spec.rb +0 -1
  469. data/spec/helpers/{admin → alchemy/admin}/tags_helper_spec.rb +1 -3
  470. data/spec/helpers/{base_helper_spec.rb → alchemy/base_helper_spec.rb} +1 -2
  471. data/spec/helpers/{elements_block_helper_spec.rb → alchemy/elements_block_helper_spec.rb} +3 -3
  472. data/spec/helpers/{elements_helper_spec.rb → alchemy/elements_helper_spec.rb} +18 -19
  473. data/spec/helpers/alchemy/essences_helper_spec.rb +85 -0
  474. data/spec/helpers/{pages_helper_spec.rb → alchemy/pages_helper_spec.rb} +125 -39
  475. data/spec/helpers/alchemy/picture_url_helpers_spec.rb +78 -0
  476. data/spec/helpers/{url_helper_spec.rb → alchemy/url_helper_spec.rb} +66 -40
  477. data/spec/libraries/config_spec.rb +2 -3
  478. data/spec/libraries/controller_actions_spec.rb +18 -18
  479. data/spec/libraries/i18n_spec.rb +7 -0
  480. data/spec/libraries/page_layout_spec.rb +13 -7
  481. data/spec/libraries/paths_spec.rb +15 -0
  482. data/spec/libraries/permissions_spec.rb +6 -7
  483. data/spec/libraries/resource_spec.rb +48 -75
  484. data/spec/libraries/resources_helper_spec.rb +55 -6
  485. data/spec/libraries/shell_spec.rb +0 -4
  486. data/spec/libraries/template_tracker_spec.rb +4 -13
  487. data/spec/libraries/tinymce_spec.rb +53 -9
  488. data/spec/mailers/{messages_spec.rb → alchemy/messages_spec.rb} +0 -2
  489. data/spec/models/{attachment_spec.rb → alchemy/attachment_spec.rb} +43 -20
  490. data/spec/models/{cell_spec.rb → alchemy/cell_spec.rb} +2 -3
  491. data/spec/models/{content_spec.rb → alchemy/content_spec.rb} +179 -70
  492. data/spec/models/{element_spec.rb → alchemy/element_spec.rb} +315 -70
  493. data/spec/models/{element_to_page_spec.rb → alchemy/element_to_page_spec.rb} +0 -1
  494. data/spec/models/{essence_boolean_spec.rb → alchemy/essence_boolean_spec.rb} +0 -0
  495. data/spec/models/{essence_date_spec.rb → alchemy/essence_date_spec.rb} +2 -3
  496. data/spec/models/{essence_file_spec.rb → alchemy/essence_file_spec.rb} +2 -5
  497. data/spec/models/{essence_html_spec.rb → alchemy/essence_html_spec.rb} +1 -1
  498. data/spec/models/{essence_link_spec.rb → alchemy/essence_link_spec.rb} +0 -0
  499. data/spec/models/{essence_picture_spec.rb → alchemy/essence_picture_spec.rb} +101 -29
  500. data/spec/models/{essence_richtext_spec.rb → alchemy/essence_richtext_spec.rb} +7 -2
  501. data/spec/models/{essence_select_spec.rb → alchemy/essence_select_spec.rb} +0 -0
  502. data/spec/models/{essence_text_spec.rb → alchemy/essence_text_spec.rb} +4 -8
  503. data/spec/models/alchemy/language_spec.rb +243 -0
  504. data/spec/models/{legacy_page_url_spec.rb → alchemy/legacy_page_url_spec.rb} +1 -1
  505. data/spec/models/{message_spec.rb → alchemy/message_spec.rb} +0 -0
  506. data/spec/models/{page_spec.rb → alchemy/page_spec.rb} +460 -248
  507. data/spec/models/{picture_spec.rb → alchemy/picture_spec.rb} +118 -30
  508. data/spec/models/{site_spec.rb → alchemy/site_spec.rb} +19 -84
  509. data/spec/models/{tag_spec.rb → alchemy/tag_spec.rb} +1 -3
  510. data/spec/models/dummy_model_spec.rb +1 -2
  511. data/spec/requests/alchemy/admin/resources_requests_spec.rb +26 -0
  512. data/spec/requests/alchemy/admin/site_requests_spec.rb +19 -0
  513. data/spec/requests/alchemy/site_requests_spec.rb +18 -0
  514. data/spec/requests/alchemy/sitemap_spec.rb +56 -0
  515. data/spec/routing/api_routing_spec.rb +1 -1
  516. data/spec/routing/routing_spec.rb +121 -15
  517. data/spec/spec_helper.rb +2 -1
  518. data/spec/support/hint_examples.rb +1 -3
  519. data/spec/support/test_tweaks.rb +3 -3
  520. data/spec/support/transformation_examples.rb +6 -7
  521. data/spec/tasks/helpers_spec.rb +2 -4
  522. data/spec/views/admin/pictures/show_spec.rb +43 -0
  523. data/spec/views/essences/essence_boolean_editor_spec.rb +0 -1
  524. data/spec/views/essences/essence_boolean_view_spec.rb +2 -4
  525. data/spec/views/essences/essence_date_view_spec.rb +0 -1
  526. data/spec/views/essences/essence_file_editor_spec.rb +4 -6
  527. data/spec/views/essences/essence_file_view_spec.rb +56 -3
  528. data/spec/views/essences/essence_link_view_spec.rb +1 -1
  529. data/spec/views/essences/essence_picture_editor_spec.rb +80 -0
  530. data/spec/views/essences/essence_picture_view_spec.rb +0 -1
  531. data/spec/views/essences/essence_select_view_spec.rb +0 -1
  532. data/spec/views/essences/essence_text_view_spec.rb +0 -1
  533. data/vendor/assets/javascripts/handlebars.js +4608 -0
  534. data/vendor/assets/javascripts/tinymce/langs/de.js +19 -0
  535. data/vendor/assets/javascripts/tinymce/langs/es.js +19 -0
  536. data/vendor/assets/javascripts/tinymce/langs/fr.js +23 -4
  537. data/vendor/assets/javascripts/tinymce/langs/nl.js +22 -3
  538. data/vendor/assets/javascripts/tinymce/langs/ru.js +22 -3
  539. data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.min.js +1 -1
  540. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.min.js +1 -1
  541. data/vendor/assets/javascripts/tinymce/themes/modern/theme.min.js +1 -1
  542. data/vendor/assets/javascripts/tinymce/tinymce.min.js +12 -13
  543. metadata +274 -256
  544. data/app/views/alchemy/admin/attachments/create.js.erb +0 -11
  545. data/app/views/alchemy/admin/attachments/new.html.erb +0 -14
  546. data/app/views/alchemy/admin/elements/_element_foot.html.erb +0 -36
  547. data/app/views/alchemy/admin/partials/_upload_form.html.erb +0 -67
  548. data/app/views/alchemy/admin/pictures/info.html.erb +0 -38
  549. data/app/views/alchemy/admin/pictures/new.html.erb +0 -16
  550. data/lib/alchemy/middleware/rescue_old_cookies.rb +0 -27
  551. data/spec/controllers/admin/resources_controller_spec.rb +0 -53
  552. data/spec/controllers/base_controller_spec.rb +0 -51
  553. data/spec/helpers/essences_helper_spec.rb +0 -156
  554. data/spec/helpers/picture_url_helpers_spec.rb +0 -35
  555. data/spec/libraries/on_page_layout_spec.rb +0 -112
  556. data/spec/models/language_spec.rb +0 -123
@@ -25,7 +25,6 @@ class ResourcesControllerForEngine
25
25
  end
26
26
  end
27
27
 
28
-
29
28
  describe Alchemy::ResourcesHelper do
30
29
  let(:controller) { ResourcesController.new }
31
30
  let(:resource_item) { double('resource-item') }
@@ -54,7 +53,7 @@ describe Alchemy::ResourcesHelper do
54
53
 
55
54
  describe "#resource_scope" do
56
55
  it "returns an array containing a proxy and namespaces for url_for-based helper-methods" do
57
- expect(controller.resource_scope).to eq(%W[main_app_proxy admin])
56
+ expect(controller.resource_scope).to eq(%w[main_app_proxy admin])
58
57
  end
59
58
  end
60
59
 
@@ -114,24 +113,58 @@ describe Alchemy::ResourcesHelper do
114
113
  end
115
114
 
116
115
  describe "#render_attribute" do
116
+ subject { controller.render_attribute(resource_item, attributes, options) }
117
+
118
+ let(:options) { {} }
119
+ let(:attributes) { {name: 'name'} }
120
+
117
121
  it "should return the value from resource attribute" do
118
122
  allow(resource_item).to receive(:name).and_return('my-name')
119
- expect(controller.render_attribute(resource_item, {name: 'name'})).to eq('my-name')
123
+ is_expected.to eq('my-name')
120
124
  end
121
125
 
122
126
  context "resource having a relation" do
123
127
  let(:associated_object) { double("location", title: 'Title of related object') }
124
128
  let(:associated_klass) { double("klass", find: associated_object) }
125
- let(:relation) {
129
+ let(:relation) do
126
130
  {
127
131
  attr_method: 'title',
128
132
  model_association: OpenStruct.new(klass: associated_klass)
129
133
  }
130
- }
134
+ end
135
+ let(:attributes) do
136
+ {name: 'name', relation: relation}
137
+ end
131
138
 
132
139
  it "should return the value from the related object attribute" do
133
140
  allow(resource_item).to receive(:name).and_return('my-name')
134
- expect(controller.render_attribute(resource_item, {name: 'name', relation: relation})).to eq('Title of related object')
141
+ is_expected.to eq('Title of related object')
142
+ end
143
+ end
144
+
145
+ context 'with long values' do
146
+ before do
147
+ allow(resource_item).to receive(:name).and_return('*' * 51)
148
+ end
149
+
150
+ it 'truncates the values' do
151
+ expect(subject.length).to eq(50)
152
+ end
153
+
154
+ context 'but with options[:truncate] set to 10' do
155
+ let(:options) { {truncate: 10} }
156
+
157
+ it 'does not truncate the values' do
158
+ expect(subject.length).to eq(10)
159
+ end
160
+ end
161
+
162
+ context 'but with options[:truncate] set to false' do
163
+ let(:options) { {truncate: false} }
164
+
165
+ it 'does not truncate the values' do
166
+ expect(subject.length).to eq(51)
167
+ end
135
168
  end
136
169
  end
137
170
  end
@@ -141,4 +174,20 @@ describe Alchemy::ResourcesHelper do
141
174
  expect(controller.resource_name).to eq("my_resource")
142
175
  end
143
176
  end
177
+
178
+ describe '#current_location_params' do
179
+ let(:params) { {q: "some_query", page: 6, action: "some_action"} }
180
+
181
+ before do
182
+ allow(controller).to receive(:params) { params }
183
+ end
184
+
185
+ it 'returns the current location params' do
186
+ expect(controller.current_location_params).to eq({q: "some_query", page: 6})
187
+ end
188
+
189
+ it 'only includes the q and page parameters' do
190
+ expect(controller.current_location_params).not_to have_key(:action)
191
+ end
192
+ end
144
193
  end
@@ -2,14 +2,12 @@ require 'spec_helper'
2
2
  require 'alchemy/shell'
3
3
 
4
4
  module Alchemy
5
-
6
5
  # Class fixture
7
6
  class MyToDoList
8
7
  extend Shell
9
8
  end
10
9
 
11
10
  describe Shell do
12
-
13
11
  before { allow(MyToDoList).to receive(:puts) }
14
12
 
15
13
  describe '.todo' do
@@ -98,7 +96,6 @@ module Alchemy
98
96
  end
99
97
 
100
98
  describe '.color' do
101
-
102
99
  context 'if given name is a constant of Thor::Shell::Color' do
103
100
  before do
104
101
  allow(Thor::Shell::Color).to receive(:const_defined?).and_return(true)
@@ -120,6 +117,5 @@ module Alchemy
120
117
  end
121
118
  end
122
119
  end
123
-
124
120
  end
125
121
  end
@@ -46,8 +46,8 @@ module Alchemy
46
46
  let(:name) { 'alchemy/elements/_text_view' }
47
47
  let(:elements) { [{'name' => 'text', 'contents' => [{'type' => 'EssenceText'}]}] }
48
48
 
49
- context 'that is having a description' do
50
- before { allow(Element).to receive(:descriptions).and_return(elements) }
49
+ context 'that is having a definition' do
50
+ before { allow(Element).to receive(:definitions).and_return(elements) }
51
51
 
52
52
  it "returns all essence layout view partial names for that element" do
53
53
  is_expected.to include('alchemy/essences/_essence_text_view')
@@ -60,18 +60,10 @@ module Alchemy
60
60
  is_expected.to include('alchemy/essences/_essence_picture_view')
61
61
  end
62
62
  end
63
-
64
- context 'and element has available_contents defined' do
65
- let(:elements) { [{'name' => 'text', 'available_contents' => ['type' => 'EssenceFile']}] }
66
-
67
- it "has these essences as template dependency" do
68
- is_expected.to include('alchemy/essences/_essence_file_view')
69
- end
70
- end
71
63
  end
72
64
 
73
- context 'that has no description' do
74
- before { allow(Element).to receive(:descriptions).and_return([]) }
65
+ context 'that has no definition' do
66
+ before { allow(Element).to receive(:definitions).and_return([]) }
75
67
 
76
68
  it "returns empty array" do
77
69
  is_expected.to be_empty
@@ -88,7 +80,6 @@ module Alchemy
88
80
  end
89
81
  end
90
82
  end
91
-
92
83
  end
93
84
  end
94
85
  end
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe Tinymce do
5
-
6
5
  describe '.init' do
7
6
  subject { Tinymce.init }
8
7
 
@@ -21,8 +20,23 @@ module Alchemy
21
20
  end
22
21
 
23
22
  context 'Methods for contents with custom tinymce config.' do
24
- let(:content_definition) { {'name' => 'text', 'settings' => {'tinymce' => {'foo' => 'bar'}}} }
25
- let(:element_definition) { {'name' => 'article', 'contents' => [content_definition]} }
23
+ let(:content_definition) do
24
+ {
25
+ 'name' => 'text',
26
+ 'settings' => {
27
+ 'tinymce' => {
28
+ 'foo' => 'bar'
29
+ }
30
+ }
31
+ }
32
+ end
33
+
34
+ let(:element_definition) do
35
+ {
36
+ 'name' => 'article',
37
+ 'contents' => [content_definition]
38
+ }
39
+ end
26
40
 
27
41
  describe '.custom_config_contents' do
28
42
  subject { Tinymce.custom_config_contents }
@@ -33,18 +47,47 @@ module Alchemy
33
47
  Tinymce.class_variable_set('@@custom_config_contents', nil)
34
48
  end
35
49
 
36
- it "returns an array of content definitions that contain custom tinymce config and element name" do
50
+ it "returns an array of content definitions that contain custom tinymce config
51
+ and element name" do
37
52
  is_expected.to be_an(Array)
38
- is_expected.to include({'element' => element_definition['name']}.merge(content_definition))
53
+ is_expected.to include({
54
+ 'element' => element_definition['name']
55
+ }.merge(content_definition))
39
56
  end
40
57
 
41
58
  context 'with no contents having custom tinymce config' do
42
- let(:content_definition) { {'name' => 'text'} }
59
+ let(:content_definition) do
60
+ {'name' => 'text'}
61
+ end
62
+
43
63
  it { is_expected.to eq([]) }
44
64
  end
45
65
 
46
66
  context 'with element definition having nil as contents value' do
47
- let(:element_definition) { {'name' => 'element', 'contents' => nil} }
67
+ let(:element_definition) do
68
+ {
69
+ 'name' => 'element',
70
+ 'contents' => nil
71
+ }
72
+ end
73
+
74
+ it "returns empty array" do
75
+ is_expected.to eq([])
76
+ end
77
+ end
78
+
79
+ context 'with content settings tinymce set to true only' do
80
+ let(:element_definition) do
81
+ {
82
+ 'name' => 'element',
83
+ 'contents' => [
84
+ 'name' => 'headline',
85
+ 'settings' => {
86
+ 'tinymce' => true
87
+ }
88
+ ]
89
+ }
90
+ end
48
91
 
49
92
  it "returns empty array" do
50
93
  is_expected.to eq([])
@@ -57,11 +100,12 @@ module Alchemy
57
100
 
58
101
  it "only returns custom tinymce config for elements of that page" do
59
102
  expect(page).to receive(:element_definitions).and_return([element_definition])
60
- is_expected.to include({'element' => element_definition['name']}.merge(content_definition))
103
+ is_expected.to include(
104
+ {'element' => element_definition['name']
105
+ }.merge(content_definition))
61
106
  end
62
107
  end
63
108
  end
64
109
  end
65
-
66
110
  end
67
111
  end
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe Messages do
5
-
6
5
  let(:message) { Message.new(email: 'jon@doe.com', message: 'Lorem ipsum') }
7
6
  let(:mail) { Messages.contact_form_mail(message, 'admin@page.com', 'contact@page.com', 'Subject') }
8
7
 
@@ -18,6 +17,5 @@ module Alchemy
18
17
  it "mail body includes message" do
19
18
  expect(mail.body).to match /#{message.message}/
20
19
  end
21
-
22
20
  end
23
21
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
 
4
4
  module Alchemy
5
5
  describe Attachment do
6
- let(:file) { File.new(File.expand_path('../../fixtures/image with spaces.png', __FILE__)) }
6
+ let(:file) { File.new(File.expand_path('../../../fixtures/image with spaces.png', __FILE__)) }
7
7
  let(:attachment) { Attachment.new(file: file) }
8
8
 
9
9
  describe 'after assign' do
@@ -20,39 +20,38 @@ module Alchemy
20
20
  expect(attachment.name).to eq("image with spaces")
21
21
  end
22
22
 
23
- it "should have a valid file_name" do
24
- expect(attachment.file_name).to eq("image-with-spaces.png")
25
- end
26
-
27
23
  after { attachment.destroy }
28
24
  end
29
25
 
30
26
  describe 'urlname sanitizing' do
31
- it "should sanitize url characters in the filename" do
27
+ it "escapes unsafe url characters" do
32
28
  attachment.file_name = 'f#%&cking cute kitten pic.png'
33
- attachment.save!
34
- expect(attachment.urlname).to eq('f-cking-cute-kitten-pic.png')
29
+ expect(attachment.urlname).to eq('f%23%25%26cking+cute+kitten+pic')
30
+ end
31
+
32
+ it "removes format suffix from end of file name" do
33
+ attachment.file_name = 'pic.png.png'
34
+ expect(attachment.urlname).to eq('pic+png')
35
35
  end
36
36
 
37
- it "should sanitize lot of dots in the name" do
37
+ it "converts dots into escaped spaces" do
38
38
  attachment.file_name = 'cute.kitten.pic.png'
39
- attachment.save!
40
- expect(attachment.urlname).to eq('cute-kitten-pic.png')
39
+ expect(attachment.urlname).to eq('cute+kitten+pic')
41
40
  end
42
41
 
43
- it "should sanitize umlauts in the name" do
42
+ it "escapes umlauts in the name" do
44
43
  attachment.file_name = 'süßes katzenbild.png'
45
- attachment.save!
46
- expect(attachment.urlname).to eq('suesses-katzenbild.png')
44
+ expect(attachment.urlname).to eq('s%C3%BC%C3%9Fes+katzenbild')
47
45
  end
48
-
49
- after { attachment.destroy }
50
46
  end
51
47
 
52
48
  describe 'validations' do
53
-
54
49
  context "having a png, but only pdf allowed" do
55
- before { allow(Config).to receive(:get).and_return({'allowed_filetypes' => {'attachments' => ['pdf']}}) }
50
+ before do
51
+ allow(Config).to receive(:get) do
52
+ {'allowed_filetypes' => {'alchemy/attachments' => ['pdf']}}
53
+ end
54
+ end
56
55
 
57
56
  it "should not be valid" do
58
57
  expect(attachment).not_to be_valid
@@ -60,13 +59,38 @@ module Alchemy
60
59
  end
61
60
 
62
61
  context "having a png and everything allowed" do
63
- before { allow(Config).to receive(:get).and_return({'allowed_filetypes' => {'attachments' => ['*']}}) }
62
+ before do
63
+ allow(Config).to receive(:get) do
64
+ {'allowed_filetypes' => {'alchemy/attachments' => ['*']}}
65
+ end
66
+ end
64
67
 
65
68
  it "should be valid" do
66
69
  expect(attachment).to be_valid
67
70
  end
68
71
  end
69
72
 
73
+ context "having a filename with special characters" do
74
+ before do
75
+ attachment.file_name = 'my FileNämü.pdf'
76
+ attachment.save
77
+ end
78
+
79
+ it "should be valid" do
80
+ expect(attachment).to be_valid
81
+ end
82
+ end
83
+
84
+ context "having a filename with unallowed character" do
85
+ before do
86
+ attachment.file_name = 'my FileNämü?!.pdf'
87
+ attachment.save
88
+ end
89
+
90
+ it "should not be valid" do
91
+ expect(attachment).not_to be_valid
92
+ end
93
+ end
70
94
  end
71
95
 
72
96
  context 'PNG image' do
@@ -222,6 +246,5 @@ module Alchemy
222
246
  it { is_expected.to be_falsey }
223
247
  end
224
248
  end
225
-
226
249
  end
227
250
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe Cell do
5
- let(:cell) { FactoryGirl.build(:cell) }
5
+ let(:cell) { build(:alchemy_cell) }
6
6
 
7
7
  # class methods
8
8
 
@@ -12,7 +12,7 @@ module Alchemy
12
12
  end
13
13
 
14
14
  it "should allow erb generated definitions" do
15
- expect(Cell.definitions.collect { |d| d['name']} ).to include('erb_cell')
15
+ expect(Cell.definitions.collect { |d| d['name'] }).to include('erb_cell')
16
16
  end
17
17
  end
18
18
 
@@ -97,6 +97,5 @@ module Alchemy
97
97
  cell.name_for_label
98
98
  end
99
99
  end
100
-
101
100
  end
102
101
  end
@@ -2,11 +2,11 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe Content do
5
- let(:element) { create(:element, name: 'headline', create_contents_after_create: true) }
5
+ let(:element) { create(:alchemy_element, name: 'headline', create_contents_after_create: true) }
6
6
  let(:content) { element.contents.find_by(essence_type: 'Alchemy::EssenceText') }
7
7
 
8
8
  it "should return the ingredient from its essence" do
9
- content.essence.update_attributes(:body => "Hello")
9
+ content.essence.update_attributes(body: "Hello")
10
10
  expect(content.ingredient).to eq("Hello")
11
11
  end
12
12
 
@@ -33,13 +33,13 @@ module Alchemy
33
33
  describe '#normalized_essence_type' do
34
34
  context "without namespace in essence_type column" do
35
35
  it "should return the namespaced essence type" do
36
- expect(Content.new(:essence_type => 'EssenceText').normalized_essence_type).to eq('Alchemy::EssenceText')
36
+ expect(Content.new(essence_type: 'EssenceText').normalized_essence_type).to eq('Alchemy::EssenceText')
37
37
  end
38
38
  end
39
39
 
40
40
  context "with namespace in essence_type column" do
41
41
  it "should return the namespaced essence type" do
42
- expect(Content.new(:essence_type => 'Alchemy::EssenceText').normalized_essence_type).to eq('Alchemy::EssenceText')
42
+ expect(Content.new(essence_type: 'Alchemy::EssenceText').normalized_essence_type).to eq('Alchemy::EssenceText')
43
43
  end
44
44
  end
45
45
  end
@@ -47,7 +47,7 @@ module Alchemy
47
47
  describe '#update_essence' do
48
48
  subject { content.update_essence(params) }
49
49
 
50
- let(:element) { create(:element, name: 'text', create_contents_after_create: true) }
50
+ let(:element) { create(:alchemy_element, name: 'text', create_contents_after_create: true) }
51
51
  let(:content) { element.contents.first }
52
52
  let(:params) { {} }
53
53
 
@@ -71,7 +71,7 @@ module Alchemy
71
71
  end
72
72
 
73
73
  context 'with validations and without params given' do
74
- let(:element) { create(:element, name: 'contactform', create_contents_after_create: true) }
74
+ let(:element) { create(:alchemy_element, name: 'contactform', create_contents_after_create: true) }
75
75
 
76
76
  it "should add error messages if save fails and return false" do
77
77
  is_expected.to be_falsey
@@ -92,79 +92,58 @@ module Alchemy
92
92
 
93
93
  describe '.copy' do
94
94
  before(:each) do
95
- @element = FactoryGirl.create(:element, :name => 'text', :create_contents_after_create => true)
95
+ @element = create(:alchemy_element, name: 'text', create_contents_after_create: true)
96
96
  @content = @element.contents.first
97
97
  end
98
98
 
99
99
  it "should create a new record with all attributes of source except given differences" do
100
- copy = Content.copy(@content, {:name => 'foobar', :element_id => @element.id + 1})
100
+ copy = Content.copy(@content, {name: 'foobar', element_id: @element.id + 1})
101
101
  expect(copy.name).to eq('foobar')
102
102
  end
103
103
 
104
104
  it "should make a new record for essence of source" do
105
- copy = Content.copy(@content, {:element_id => @element.id + 1})
105
+ copy = Content.copy(@content, {element_id: @element.id + 1})
106
106
  expect(copy.essence_id).not_to eq(@content.essence_id)
107
107
  end
108
108
 
109
109
  it "should copy source essence attributes" do
110
- copy = Content.copy(@content, {:element_id => @element.id + 1})
110
+ copy = Content.copy(@content, {element_id: @element.id + 1})
111
111
  copy.essence.body == @content.essence.body
112
112
  end
113
113
  end
114
114
 
115
115
  describe '.build' do
116
- let(:element) { FactoryGirl.build_stubbed(:element) }
116
+ let(:element) { build_stubbed(:alchemy_element) }
117
117
 
118
- it "builds a new instance from elements.yml description" do
118
+ it "builds a new instance from elements.yml definition" do
119
119
  expect(Content.build(element, {name: 'headline'})).to be_instance_of(Content)
120
120
  end
121
121
  end
122
122
 
123
- describe '.content_description' do
124
- let(:element) { FactoryGirl.build_stubbed(:element) }
123
+ describe '.content_definition' do
124
+ let(:element) { build_stubbed(:alchemy_element) }
125
125
 
126
126
  context "with blank name key" do
127
127
  it "returns a essence hash build from essence type" do
128
- expect(Content).to receive(:content_description_from_essence_type).with(element, 'EssenceText')
129
- Content.content_description(element, essence_type: 'EssenceText')
128
+ expect(Content).to receive(:content_definition_from_essence_type).with(element, 'EssenceText')
129
+ Content.content_definition(element, essence_type: 'EssenceText')
130
130
  end
131
131
  end
132
132
 
133
133
  context "with name key present" do
134
134
  it "returns a essence hash from element" do
135
- expect(Content).to receive(:content_description_from_element).with(element, 'headline')
136
- Content.content_description(element, name: 'headline')
135
+ expect(element).to receive(:content_definition_for).with('headline')
136
+ Content.content_definition(element, name: 'headline')
137
137
  end
138
138
  end
139
139
  end
140
140
 
141
- describe '.content_description_from_element' do
142
- let(:element) { FactoryGirl.build_stubbed(:element) }
143
- let(:essence) { {name: 'headline', type: 'EssenceText'} }
141
+ describe '.content_definition_from_essence_type' do
142
+ let(:element) { build_stubbed(:alchemy_element) }
144
143
 
145
- it "returns the description hash from element" do
146
- expect(element).to receive(:content_description_for).and_return(essence)
147
- expect(Content.content_description(element, name: 'headline')).to eq(essence)
148
- end
149
-
150
- context "with content description not found" do
151
- before {
152
- expect(element).to receive(:content_description_for).and_return(nil)
153
- expect(element).to receive(:available_content_description_for).and_return(essence)
154
- }
155
-
156
- it "returns the description hash from available contents" do
157
- expect(Content.content_description(element, name: 'headline')).to eq(essence)
158
- end
159
- end
160
- end
161
-
162
- describe '.content_description_from_essence_type' do
163
- let(:element) { FactoryGirl.build_stubbed(:element) }
164
-
165
- it "returns the description hash from element" do
144
+ it "returns the definition hash from element" do
166
145
  expect(Content).to receive(:content_name_from_element_and_essence_type).with(element, 'EssenceText').and_return('Foo')
167
- expect(Content.content_description_from_essence_type(element, 'EssenceText')).to eq({
146
+ expect(Content.content_definition_from_essence_type(element, 'EssenceText')).to eq({
168
147
  'type' => 'EssenceText',
169
148
  'name' => 'Foo'
170
149
  })
@@ -172,7 +151,7 @@ module Alchemy
172
151
  end
173
152
 
174
153
  describe '.content_name_from_element_and_essence_type' do
175
- let(:element) { FactoryGirl.build_stubbed(:element) }
154
+ let(:element) { build_stubbed(:alchemy_element) }
176
155
 
177
156
  it "returns a name from essence type and count of essences in element" do
178
157
  expect(Content.content_name_from_element_and_essence_type(element, 'EssenceText')).to eq("essence_text_1")
@@ -180,7 +159,7 @@ module Alchemy
180
159
  end
181
160
 
182
161
  describe '.create_from_scratch' do
183
- let(:element) { FactoryGirl.create(:element, name: 'article') }
162
+ let(:element) { create(:alchemy_element, name: 'article') }
184
163
 
185
164
  it "builds the content" do
186
165
  expect(Content.create_from_scratch(element, name: 'headline')).to be_instance_of(Alchemy::Content)
@@ -196,7 +175,9 @@ module Alchemy
196
175
 
197
176
  context "with default value present" do
198
177
  it "should have the ingredient column filled with default value." do
199
- allow(Content).to receive(:content_description_from_element).and_return({'name' => 'headline', 'type' => 'EssenceText', 'default' => 'Welcome'})
178
+ allow_any_instance_of(Element).to receive(:content_definition_for) do
179
+ {'name' => 'headline', 'type' => 'EssenceText', 'default' => 'Welcome'}
180
+ end
200
181
  content = Content.create_from_scratch(element, name: 'headline')
201
182
  expect(content.ingredient).to eq("Welcome")
202
183
  end
@@ -204,7 +185,7 @@ module Alchemy
204
185
  end
205
186
 
206
187
  describe '#ingredient=' do
207
- let(:element) { FactoryGirl.create(:element, name: 'headline') }
188
+ let(:element) { create(:alchemy_element, name: 'headline') }
208
189
 
209
190
  it "should set the given value to the ingredient column of essence" do
210
191
  c = Content.create_from_scratch(element, name: 'headline')
@@ -213,27 +194,27 @@ module Alchemy
213
194
  end
214
195
 
215
196
  context "no essence associated" do
216
- let(:element) { FactoryGirl.create(:element, name: 'headline') }
197
+ let(:element) { create(:alchemy_element, name: 'headline') }
217
198
 
218
199
  it "should raise error" do
219
- c = Content.create(:element_id => element.id, name: 'headline')
220
- expect { c.ingredient = "Welcome" }.to raise_error(EssenceMissingError)
200
+ content = Content.create(element_id: element.id, name: 'headline')
201
+ expect { content.ingredient = "Welcome" }.to raise_error(EssenceMissingError)
221
202
  end
222
203
  end
223
204
  end
224
205
 
225
- describe "#descriptions" do
226
- context "without any descriptions in elements.yml file" do
227
- before { allow(Element).to receive(:descriptions).and_return([]) }
206
+ describe "#definitions" do
207
+ context "without any definitions in elements.yml file" do
208
+ before { allow(Element).to receive(:definitions).and_return([]) }
228
209
 
229
210
  it "should return an empty array" do
230
- expect(Content.descriptions).to eq([])
211
+ expect(Content.definitions).to eq([])
231
212
  end
232
213
  end
233
214
  end
234
215
 
235
216
  describe "#dom_id" do
236
- let(:content) { build_stubbed(:content) }
217
+ let(:content) { build_stubbed(:alchemy_content) }
237
218
 
238
219
  it "returns a dom id string" do
239
220
  expect(content.dom_id).to eq("essence_text_#{content.id}")
@@ -249,7 +230,7 @@ module Alchemy
249
230
  end
250
231
 
251
232
  describe "#essence_partial_name" do
252
- let(:content) { build_stubbed(:content) }
233
+ let(:content) { build_stubbed(:alchemy_content) }
253
234
 
254
235
  it "returns the essence#partial_name" do
255
236
  expect(content.essence).to receive(:partial_name)
@@ -266,7 +247,7 @@ module Alchemy
266
247
  end
267
248
 
268
249
  describe '#preview_content?' do
269
- let(:content) { build_stubbed(:content) }
250
+ let(:content) { build_stubbed(:alchemy_content) }
270
251
 
271
252
  context 'not defined as preview content' do
272
253
  it "returns false" do
@@ -276,7 +257,7 @@ module Alchemy
276
257
 
277
258
  context 'defined as preview content via take_me_for_preview' do
278
259
  before do
279
- expect(content).to receive(:description).at_least(:once).and_return({
260
+ expect(content).to receive(:definition).at_least(:once).and_return({
280
261
  'take_me_for_preview' => true
281
262
  })
282
263
  end
@@ -295,7 +276,7 @@ module Alchemy
295
276
 
296
277
  context 'defined as preview content via as_element_title' do
297
278
  before do
298
- expect(content).to receive(:description).at_least(:once).and_return({
279
+ expect(content).to receive(:definition).at_least(:once).and_return({
299
280
  'as_element_title' => true
300
281
  })
301
282
  end
@@ -316,16 +297,68 @@ module Alchemy
316
297
  end
317
298
  end
318
299
 
300
+ describe '#has_tinymce?' do
301
+ let(:element) { build_stubbed(:alchemy_element, name: 'article') }
302
+ let(:content) { build_stubbed(:alchemy_content, name: 'text', element: element) }
303
+
304
+ subject { content.has_tinymce? }
305
+
306
+ it { is_expected.to eq(false) }
307
+
308
+ context 'having custom tinymce config hash' do
309
+ before do
310
+ expect(content).to receive(:settings) do
311
+ {tinymce: {toolbar: []}}
312
+ end
313
+ end
314
+
315
+ it { is_expected.to eq(true) }
316
+ end
317
+
318
+ context 'having essence that has_tinymce? eq true' do
319
+ before do
320
+ expect(content.essence).to receive(:has_tinymce?) { true }
321
+ end
322
+
323
+ it { is_expected.to eq(true) }
324
+ end
325
+ end
326
+
327
+ describe '#has_custom_tinymce_config?' do
328
+ let(:element) { build_stubbed(:alchemy_element, name: 'article') }
329
+ let(:content) { build_stubbed(:alchemy_content, name: 'text', element: element) }
330
+
331
+ subject { content.has_custom_tinymce_config? }
332
+
333
+ it { is_expected.to eq(false) }
334
+
335
+ context 'having custom tinymce config hash' do
336
+ before do
337
+ expect(content).to receive(:settings) do
338
+ {tinymce: {toolbar: []}}
339
+ end
340
+ end
341
+
342
+ it { is_expected.to eq(true) }
343
+ end
344
+ end
345
+
319
346
  describe '#tinymce_class_name' do
320
- let(:element) { FactoryGirl.build_stubbed(:element, name: 'article') }
321
- let(:content) { c = Content.new(name: 'text'); c.element = element; c }
347
+ let(:element) { build_stubbed(:alchemy_element, name: 'article') }
348
+ let(:content) { build_stubbed(:alchemy_content, name: 'text', element: element) }
349
+
322
350
  subject { content.tinymce_class_name }
323
351
 
324
- it { eq('default_tinymce') }
352
+ it { is_expected.to eq('has_tinymce') }
325
353
 
326
354
  context 'having custom tinymce config' do
327
- before { allow(content).to receive(:has_custom_tinymce_config?).and_return(true) }
328
- it('returns name including element name') { eq('custom_tinymce article_text') }
355
+ before do
356
+ expect(content).to receive(:has_custom_tinymce_config?).and_return(true)
357
+ end
358
+
359
+ it 'returns name including element name' do
360
+ is_expected.to eq('has_tinymce article_text')
361
+ end
329
362
  end
330
363
  end
331
364
 
@@ -362,15 +395,15 @@ module Alchemy
362
395
  end
363
396
 
364
397
  describe '#settings' do
365
- let(:element) { build_stubbed(:element, name: 'article') }
366
- let(:content) { build_stubbed(:content, name: 'headline', element: element) }
398
+ let(:element) { build_stubbed(:alchemy_element, name: 'article') }
399
+ let(:content) { build_stubbed(:alchemy_content, name: 'headline', element: element) }
367
400
 
368
- it "returns the settings hash from description" do
369
- expect(content.settings).to eq({deletable: true})
401
+ it "returns the settings hash from definition" do
402
+ expect(content.settings).to eq({linkable: true})
370
403
  end
371
404
 
372
405
  context 'if settings are not defined' do
373
- let(:content) { build_stubbed(:content, name: 'intro', element: element) }
406
+ let(:content) { build_stubbed(:alchemy_content, name: 'intro', element: element) }
374
407
 
375
408
  it "returns empty hash" do
376
409
  expect(content.settings).to eq({})
@@ -378,8 +411,84 @@ module Alchemy
378
411
  end
379
412
  end
380
413
 
414
+ describe '#settings_value' do
415
+ let(:key) { :key }
416
+ let(:settings) { Hash.new }
417
+
418
+ subject { content.settings_value(key, options) }
419
+
420
+ before do
421
+ allow(content).to receive(:settings) { settings }
422
+ end
423
+
424
+ context 'with content having settings' do
425
+ let(:settings) { {key: 'settings_value'} }
426
+
427
+ context 'and empty options' do
428
+ let(:options) { {} }
429
+
430
+ it "returns the value for key from content settings" do
431
+ expect(subject).to eq('settings_value')
432
+ end
433
+ end
434
+
435
+ context 'and nil options' do
436
+ let(:options) { nil }
437
+
438
+ it "returns the value for key from content settings" do
439
+ expect(subject).to eq('settings_value')
440
+ end
441
+ end
442
+
443
+ context 'but same key present in options' do
444
+ let(:options) { {key: 'options_value'} }
445
+
446
+ it "returns the value for key from options" do
447
+ expect(subject).to eq('options_value')
448
+ end
449
+ end
450
+ end
451
+
452
+ context 'with content having no settings' do
453
+ let(:settings) { {} }
454
+
455
+ context 'and empty options' do
456
+ let(:options) { {} }
457
+
458
+ it { expect(subject).to eq(nil) }
459
+ end
460
+
461
+ context 'but key present in options' do
462
+ let(:options) { {key: 'options_value'} }
463
+
464
+ it "returns the value for key from options" do
465
+ expect(subject).to eq('options_value')
466
+ end
467
+ end
468
+ end
469
+
470
+ context 'with content having settings with string as key' do
471
+ let(:settings) { {'key' => 'value_from_string_key'} }
472
+ let(:options) { {} }
473
+
474
+ it "returns value" do
475
+ expect(subject).to eq('value_from_string_key')
476
+ end
477
+ end
478
+
479
+ context 'with key passed as string' do
480
+ let(:settings) { {key: 'value_from_symbol_key'} }
481
+ let(:key) { 'key' }
482
+ let(:options) { {} }
483
+
484
+ it "returns value" do
485
+ expect(subject).to eq('value_from_symbol_key')
486
+ end
487
+ end
488
+ end
489
+
381
490
  context 'delegations' do
382
- let(:page) { create(:restricted_page) }
491
+ let(:page) { create(:alchemy_page, :restricted) }
383
492
 
384
493
  it "delegates restricted? to page" do
385
494
  element.update!(page: page)