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
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe ElementToPage do
5
-
6
5
  # ClassMethods
7
6
 
8
7
  describe '.table_name' do
@@ -6,7 +6,7 @@ module Alchemy
6
6
 
7
7
  it_behaves_like "an essence" do
8
8
  let(:essence) { EssenceDate.new }
9
- let(:ingredient_value) { DateTime.now }
9
+ let(:ingredient_value) { DateTime.current }
10
10
  end
11
11
 
12
12
  describe '#preview_text' do
@@ -18,12 +18,11 @@ module Alchemy
18
18
 
19
19
  context "if date set" do
20
20
  it "should format the date by i18n" do
21
- essence.date = DateTime.now
21
+ essence.date = DateTime.current
22
22
  expect(::I18n).to receive(:l).with(essence.date, format: :date)
23
23
  essence.preview_text
24
24
  end
25
25
  end
26
26
  end
27
-
28
27
  end
29
28
  end
@@ -2,8 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe EssenceFile do
5
-
6
- let(:attachment) { build_stubbed(:attachment) }
5
+ let(:attachment) { build_stubbed(:alchemy_attachment) }
7
6
  let(:essence) { EssenceFile.new(attachment: attachment) }
8
7
 
9
8
  it_behaves_like "an essence" do
@@ -15,7 +14,7 @@ module Alchemy
15
14
  subject { essence.attachment_url }
16
15
 
17
16
  it "returns the download attachment url." do
18
- is_expected.to match(/\/attachment\/#{attachment.id}\/download\/#{attachment.file_name}/)
17
+ is_expected.to match(/\/attachment\/#{attachment.id}\/download\/#{attachment.urlname}\.#{attachment.suffix}/)
19
18
  end
20
19
 
21
20
  context 'without attachment assigned' do
@@ -26,7 +25,6 @@ module Alchemy
26
25
  end
27
26
 
28
27
  describe '#preview_text' do
29
-
30
28
  it "returns the attachment's name as preview text" do
31
29
  expect(essence.preview_text).to eq(attachment.name)
32
30
  end
@@ -38,6 +36,5 @@ module Alchemy
38
36
  end
39
37
  end
40
38
  end
41
-
42
39
  end
43
40
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe EssenceHtml do
5
- let (:essence) { EssenceHtml.new(source: '<p>hello!</p>') }
5
+ let(:essence) { EssenceHtml.new(source: '<p>hello!</p>') }
6
6
 
7
7
  it_behaves_like "an essence" do
8
8
  let(:essence) { EssenceHtml.new }
@@ -8,25 +8,25 @@ module Alchemy
8
8
  end
9
9
 
10
10
  it_behaves_like "has image transformations" do
11
- let(:picture) { build_stubbed(:essence_picture) }
11
+ let(:picture) { build_stubbed(:alchemy_essence_picture) }
12
12
  end
13
13
 
14
14
  it "should not store negative values for crop values" do
15
- essence = EssencePicture.new(:crop_from => '-1x100', :crop_size => '-20x30')
15
+ essence = EssencePicture.new(crop_from: '-1x100', crop_size: '-20x30')
16
16
  essence.save!
17
17
  expect(essence.crop_from).to eq("0x100")
18
18
  expect(essence.crop_size).to eq("0x30")
19
19
  end
20
20
 
21
21
  it "should not store float values for crop values" do
22
- essence = EssencePicture.new(:crop_from => '0.05x104.5', :crop_size => '99.5x203.4')
22
+ essence = EssencePicture.new(crop_from: '0.05x104.5', crop_size: '99.5x203.4')
23
23
  essence.save!
24
24
  expect(essence.crop_from).to eq("0x105")
25
25
  expect(essence.crop_size).to eq("100x203")
26
26
  end
27
27
 
28
28
  it "should convert newlines in caption into <br/>s" do
29
- essence = EssencePicture.new(:caption => "hello\nkitty")
29
+ essence = EssencePicture.new(caption: "hello\nkitty")
30
30
  essence.save!
31
31
  expect(essence.caption).to eq("hello<br/>kitty")
32
32
  end
@@ -35,8 +35,8 @@ module Alchemy
35
35
  subject { essence.picture_url(options) }
36
36
 
37
37
  let(:options) { {} }
38
- let(:picture) { build_stubbed(:picture) }
39
- let(:essence) { build_stubbed(:essence_picture, picture: picture) }
38
+ let(:picture) { build_stubbed(:alchemy_picture) }
39
+ let(:essence) { build_stubbed(:alchemy_essence_picture, picture: picture) }
40
40
 
41
41
  it "returns the show picture url." do
42
42
  is_expected.to match(/\/pictures\/#{picture.id}\/show\/#{picture.urlname}\.#{Config.get(:image_output_format)}/)
@@ -68,33 +68,64 @@ module Alchemy
68
68
  end
69
69
  end
70
70
 
71
- context 'with crop sizes set' do
72
- before do
73
- expect(essence).to receive(:crop_size).at_least(:once).and_return('200x200')
74
- expect(essence).to receive(:crop_from).at_least(:once).and_return('10x10')
75
- end
71
+ context 'when cropping is allowed' do
72
+ let(:options) { {crop: true} }
76
73
 
77
- it "includes the crop sizes in the url." do
78
- is_expected.to match(/200x200/)
79
- is_expected.to match(/10x10/)
74
+ it 'converts the value `true` of the `crop` option into `crop` as part of the url' do
75
+ is_expected.to match /crop/
76
+ is_expected.not_to match /true/
80
77
  end
81
78
 
82
- context 'but with crop sizes in the options' do
83
- let(:options) { {crop_from: '30x30', crop_size: '75x75'} }
79
+ context 'and crop sizes are set' do
80
+ before do
81
+ expect(essence).to receive(:crop_size).at_least(:once).and_return('200x200')
82
+ expect(essence).to receive(:crop_from).at_least(:once).and_return('10x10')
83
+ end
84
84
 
85
- it "includes these crop sizes instead." do
86
- is_expected.to match(/30x30/)
87
- is_expected.to match(/75x75/)
85
+ it "includes the crop sizes in the url." do
86
+ is_expected.to match(/200x200/)
87
+ is_expected.to match(/10x10/)
88
+ end
89
+
90
+ context 'but with crop sizes in the options' do
91
+ before do
92
+ options.update({crop_from: '30x30', crop_size: '75x75'})
93
+ end
94
+
95
+ it "includes these crop sizes instead." do
96
+ is_expected.to match(/30x30/)
97
+ is_expected.to match(/75x75/)
98
+ end
88
99
  end
89
100
  end
90
101
  end
91
102
 
92
- context 'with crop true in the options' do
93
- let(:options) { {crop: true} }
103
+ context 'when cropping is prohibited' do
104
+ before do
105
+ expect(essence).not_to receive(:crop_size)
106
+ expect(essence).not_to receive(:crop_from)
107
+ end
94
108
 
95
- it 'converts the value into `crop`' do
96
- is_expected.to match /crop/
97
- is_expected.not_to match /true/
109
+ context 'without setting `crop` in the options' do
110
+ it "does not include `crop` in the url" do
111
+ is_expected.not_to match(/crop/)
112
+ end
113
+ end
114
+
115
+ context 'when `crop` is explicitly set to `false`' do
116
+ let(:options) { {crop: false} }
117
+
118
+ it "does not include `crop` in the url" do
119
+ is_expected.not_to match(/crop/)
120
+ end
121
+ end
122
+
123
+ context 'even when crop sizes are set' do
124
+ it "does not include any cropping information in the url" do
125
+ is_expected.not_to match(/crop/)
126
+ is_expected.not_to match(/200x200/)
127
+ is_expected.not_to match(/10x10/)
128
+ end
98
129
  end
99
130
  end
100
131
 
@@ -125,7 +156,7 @@ module Alchemy
125
156
  subject { essence.cropping_mask }
126
157
 
127
158
  context 'with crop values given' do
128
- let(:essence) { build_stubbed(:essence_picture, crop_from: '0x0', crop_size: '100x100') }
159
+ let(:essence) { build_stubbed(:alchemy_essence_picture, crop_from: '0x0', crop_size: '100x100') }
129
160
 
130
161
  it "returns a hash containing cropping coordinates" do
131
162
  is_expected.to eq({x1: 0, y1: 0, x2: 100, y2: 100})
@@ -133,14 +164,14 @@ module Alchemy
133
164
  end
134
165
 
135
166
  context 'with no crop values given' do
136
- let(:essence) { build_stubbed(:essence_picture) }
167
+ let(:essence) { build_stubbed(:alchemy_essence_picture) }
137
168
 
138
169
  it { is_expected.to be_nil }
139
170
  end
140
171
  end
141
172
 
142
173
  describe '#preview_text' do
143
- let(:picture) { mock_model(Picture, name: 'Cute Cat Kittens')}
174
+ let(:picture) { mock_model(Picture, name: 'Cute Cat Kittens') }
144
175
  let(:essence) { EssencePicture.new }
145
176
 
146
177
  it "should return the pictures name as preview text" do
@@ -157,7 +188,7 @@ module Alchemy
157
188
 
158
189
  describe '#serialized_ingredient' do
159
190
  let(:content) { Content.new }
160
- let(:picture) { mock_model(Picture, name: 'Cute Cat Kittens', urlname: 'cute-cat-kittens', security_token: 'kljhgfd')}
191
+ let(:picture) { mock_model(Picture, name: 'Cute Cat Kittens', urlname: 'cute-cat-kittens', security_token: 'kljhgfd') }
161
192
  let(:essence) { EssencePicture.new(content: content, picture: picture) }
162
193
 
163
194
  it "returns the url to render the picture" do
@@ -166,7 +197,7 @@ module Alchemy
166
197
 
167
198
  context 'with image settings given at content' do
168
199
  before do
169
- expect(content).to receive(:settings).and_return({size: '150x150', format: 'png', select_values: [1,2,3]})
200
+ expect(content).to receive(:settings).and_return({size: '150x150', format: 'png', select_values: [1, 2, 3]})
170
201
  end
171
202
 
172
203
  it "returns the url with cropping and resizing options" do
@@ -179,5 +210,46 @@ module Alchemy
179
210
  end
180
211
  end
181
212
 
213
+ describe "#allow_image_cropping?" do
214
+ let(:essence_picture) { stub_model(Alchemy::EssencePicture) }
215
+ let(:content) { stub_model(Alchemy::Content) }
216
+ let(:picture) { stub_model(Alchemy::Picture) }
217
+
218
+ subject { essence_picture.allow_image_cropping? }
219
+
220
+ it { is_expected.to be_falsy }
221
+
222
+ context "with content existing?" do
223
+ before do
224
+ allow(essence_picture).to receive(:content) { content }
225
+ end
226
+
227
+ it { is_expected.to be_falsy }
228
+
229
+ context "with picture assigned" do
230
+ before do
231
+ allow(essence_picture).to receive(:picture) { picture }
232
+ end
233
+
234
+ it { is_expected.to be_falsy }
235
+
236
+ context "and with image larger than crop size" do
237
+ before do
238
+ allow(picture).to receive(:can_be_cropped_to) { true }
239
+ end
240
+
241
+ it { is_expected.to be_falsy }
242
+
243
+ context "with crop set to true" do
244
+ before do
245
+ allow(content).to receive(:settings_value) { true }
246
+ end
247
+
248
+ it { is_expected.to be(true) }
249
+ end
250
+ end
251
+ end
252
+ end
253
+ end
182
254
  end
183
255
  end
@@ -2,10 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe EssenceRichtext do
5
- let(:essence) { EssenceRichtext.new(:body => '<h1>Hello!</h1><p>Welcome to Peters Petshop.</p>') }
5
+ let(:essence) do
6
+ EssenceRichtext.new(body: '<h1>Hello!</h1><p>Welcome to Peters Petshop.</p>')
7
+ end
6
8
 
7
9
  it_behaves_like "an essence" do
8
- let(:essence) { EssenceRichtext.new }
10
+ let(:essence) { EssenceRichtext.new }
9
11
  let(:ingredient_value) { '<h1>Hello!</h1><p>Welcome to Peters Petshop.</p>' }
10
12
  end
11
13
 
@@ -14,5 +16,8 @@ module Alchemy
14
16
  expect(essence.stripped_body).to eq("Hello!Welcome to Peters Petshop.")
15
17
  end
16
18
 
19
+ it 'has tinymce enabled' do
20
+ expect(essence.has_tinymce?).to eq(true)
21
+ end
17
22
  end
18
23
  end
@@ -17,12 +17,12 @@ module Alchemy
17
17
  end
18
18
 
19
19
  it "should return a preview text" do
20
- expect(essence.preview_text).to eq("#{ingredient_value}")
20
+ expect(essence.preview_text).to eq(ingredient_value.to_s)
21
21
  end
22
22
 
23
23
  context "with given maxlength" do
24
24
  it "should return as much beginning characters as defined with maxlength" do
25
- expect(essence.preview_text(2)).to eq("#{ingredient_value}"[0..1])
25
+ expect(essence.preview_text(2)).to eq(ingredient_value.to_s[0..1])
26
26
  end
27
27
  end
28
28
 
@@ -44,7 +44,6 @@ module Alchemy
44
44
 
45
45
  context 'essence responds to link_taget' do
46
46
  context 'if link_target attribute is set to "blank"' do
47
-
48
47
  before { essence.link_target = 'blank' }
49
48
 
50
49
  it "should return true" do
@@ -62,10 +61,9 @@ module Alchemy
62
61
 
63
62
  describe 'validations' do
64
63
  describe 'format' do
65
-
66
64
  context 'given a regex string' do
67
65
  before do
68
- allow(essence).to receive(:description).and_return({'validate' => [{'format' => /\Ahttps:\/\/[\S]+/}]})
66
+ allow(essence).to receive(:definition).and_return({'validate' => [{'format' => /\Ahttps:\/\/[\S]+/}]})
69
67
  end
70
68
 
71
69
  context 'when ingredient string does not match the given regex' do
@@ -87,7 +85,7 @@ module Alchemy
87
85
 
88
86
  context 'given a key from the config`s format_matcher list' do
89
87
  before do
90
- allow(essence).to receive(:description).and_return({'validate' => [{'format' => 'email'}]})
88
+ allow(essence).to receive(:definition).and_return({'validate' => [{'format' => 'email'}]})
91
89
  end
92
90
 
93
91
  context 'when ingredient string does not match the given format matcher' do
@@ -106,9 +104,7 @@ module Alchemy
106
104
  end
107
105
  end
108
106
  end
109
-
110
107
  end
111
108
  end
112
-
113
109
  end
114
110
  end
@@ -0,0 +1,243 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ module Alchemy
5
+ describe Language do
6
+ let(:default_language) { Alchemy::Language.default }
7
+ let(:language) { create(:alchemy_language, :klingon) }
8
+ let(:page) { create(:alchemy_page, language: language) }
9
+
10
+ it 'is valid with uppercase country code' do
11
+ language = Alchemy::Language.new(
12
+ country_code: 'AT',
13
+ language_code: 'de',
14
+ name: 'Österreich',
15
+ frontpage_name: 'Start',
16
+ page_layout: 'index'
17
+ )
18
+ expect(language).to be_valid
19
+ end
20
+
21
+ it "should return a label for code" do
22
+ expect(language.label(:code)).to eq('kl')
23
+ end
24
+
25
+ it "should return a label for name" do
26
+ expect(language.label(:name)).to eq('Klingon')
27
+ end
28
+
29
+ context "with language_code and empty country_code" do
30
+ it "#code should return language locale only" do
31
+ language.country_code = ''
32
+ expect(language.code).to eq('kl')
33
+ end
34
+
35
+ context "adding a value for country code" do
36
+ it "#code should return a joined locale" do
37
+ language.country_code = 'cr'
38
+ expect(language.code).to eq('kl-cr')
39
+ end
40
+
41
+ it "should update all associated Pages with self.code as value for Page#language_code" do
42
+ page = create(:alchemy_page, language: language)
43
+ language.country_code = 'cr'
44
+ language.save
45
+ page.reload; expect(page.language_code).to eq('kl-cr')
46
+ end
47
+ end
48
+ end
49
+
50
+ context "with country_code and_language_code" do
51
+ context "removing the country_code" do
52
+ it "should update all associated Pages´s language_code with Language#code" do
53
+ language = create(:alchemy_language, country_code: 'kl')
54
+ language.country_code = ''
55
+ language.save
56
+ page.reload; expect(page.language_code).to eq("kl")
57
+ end
58
+ end
59
+ end
60
+
61
+ it "should not be deletable if it is the default language" do
62
+ expect {
63
+ default_language.destroy
64
+ }.to raise_error(DefaultLanguageNotDeletable)
65
+ end
66
+
67
+ describe "before save" do
68
+ describe "#remove_old_default if default attribute has changed to true" do
69
+ it "should unset the default status of the old default language" do
70
+ default_language
71
+ language.update_attributes(default: true)
72
+ default_language.reload
73
+ expect(default_language.default).to be_falsey
74
+ end
75
+ end
76
+ end
77
+
78
+ context "after_update" do
79
+ describe "#set_pages_language if language´s code has changed" do
80
+ it "should update all its pages with the new code" do
81
+ @other_page = create(:alchemy_page, language: language)
82
+ language.update_attributes(code: "fo")
83
+ language.reload; page.reload; @other_page.reload
84
+ expect([page.language_code, @other_page.language_code]).to eq([language.code, language.code])
85
+ end
86
+ end
87
+
88
+ describe "#unpublish_pages" do
89
+ it "should set all pages to unpublic if it gets set to unpublic" do
90
+ page = create(:alchemy_page, language: language)
91
+ @other_page = create(:alchemy_page, language: language)
92
+ language.update_attributes(public: false)
93
+ language.reload; page.reload; @other_page.reload
94
+ expect([page.public?, @other_page.public?]).to eq([false, false])
95
+ end
96
+ end
97
+ end
98
+
99
+ describe '.find_by_code' do
100
+ context "with only the language code given" do
101
+ it "should find the language" do
102
+ expect(Language.find_by_code(language.code)).to eq(language)
103
+ end
104
+ end
105
+ end
106
+
107
+ describe 'validations' do
108
+ let(:language) { Language.new(default: true, public: false) }
109
+
110
+ describe 'publicity_of_default_language' do
111
+ context 'if language is not published' do
112
+ it "should add an error to the object" do
113
+ expect(language.valid?).to eq(false)
114
+ expect(language.errors.messages).to have_key(:public)
115
+ end
116
+ end
117
+ end
118
+
119
+ describe 'presence_of_default_language' do
120
+ context 'if no default language would exist anymore' do
121
+ before do
122
+ allow(Language).to receive(:default).and_return(language)
123
+ allow(language).to receive(:default_changed?).and_return(true)
124
+ end
125
+
126
+ it "should add an error to the object" do
127
+ expect(language.valid?).to eq(false)
128
+ expect(language.errors.messages).to have_key(:default)
129
+ end
130
+ end
131
+ end
132
+
133
+ describe 'before' do
134
+ subject do
135
+ language.valid?
136
+ language.locale
137
+ end
138
+
139
+ before do
140
+ allow(::I18n).to receive(:available_locales) do
141
+ [:de, :'de-at', :en, :'en-uk']
142
+ end
143
+ end
144
+
145
+ context 'when locale is already set' do
146
+ let(:language) do
147
+ build(:alchemy_language, language_code: 'de', locale: 'de')
148
+ end
149
+
150
+ it 'does not set the locale again' do
151
+ expect(language).to_not receive(:set_locale)
152
+ end
153
+ end
154
+
155
+ context 'when code is an available locale' do
156
+ let(:language) do
157
+ build(:alchemy_language, language_code: 'de', country_code: 'at')
158
+ end
159
+
160
+ it 'sets the locale to code' do
161
+ is_expected.to eq('de-at')
162
+ end
163
+ end
164
+
165
+ context 'when code is not is an available locale, but language_code is' do
166
+ let(:language) do
167
+ build(:alchemy_language, language_code: 'de', country_code: 'ch')
168
+ end
169
+
170
+ it 'sets the locale to language code' do
171
+ is_expected.to eq('de')
172
+ end
173
+ end
174
+
175
+ context "when language_code is an available locale" do
176
+ let(:language) do
177
+ build(:alchemy_language, language_code: 'en')
178
+ end
179
+
180
+ it 'sets the locale to language_code' do
181
+ is_expected.to eq('en')
182
+ end
183
+ end
184
+
185
+ context "when neither language_code nor code is an available locale" do
186
+ it { is_expected.to be_nil }
187
+ end
188
+ end
189
+
190
+ describe 'presence_of_locale_file' do
191
+ context "when locale file is missing for selected language code" do
192
+ let(:language) do
193
+ build(:alchemy_language, language_code: 'jp')
194
+ end
195
+
196
+ it 'adds errors to locale attribute' do
197
+ expect(language).to_not be_valid
198
+ expect(language.errors).to have_key(:locale)
199
+ end
200
+ end
201
+
202
+ context "when locale file is present for selected language code" do
203
+ let(:language) do
204
+ build(:alchemy_language, :klingon)
205
+ end
206
+
207
+ it 'adds no errors to locale attribute' do
208
+ expect(language).to be_valid
209
+ expect(language.errors).to_not have_key(:locale)
210
+ end
211
+ end
212
+ end
213
+ end
214
+
215
+ describe '#matching_locales' do
216
+ let(:language) do
217
+ build(:alchemy_language, language_code: 'de')
218
+ end
219
+
220
+ subject do
221
+ language.matching_locales
222
+ end
223
+
224
+ before do
225
+ expect(::I18n).to receive(:available_locales) do
226
+ [:de, :'de-at', :'en-uk']
227
+ end
228
+ end
229
+
230
+ it 'returns locales matching the language code' do
231
+ is_expected.to eq [:de, :'de-at']
232
+ end
233
+
234
+ context 'when language code is not is an available locale' do
235
+ let(:language) do
236
+ build(:alchemy_language, language_code: 'jp')
237
+ end
238
+
239
+ it { is_expected.to eq [] }
240
+ end
241
+ end
242
+ end
243
+ end