alchemy_cms 4.6.2 → 5.0.0.beta1

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 (378) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +33 -1
  3. data/.github/workflows/stale.yml +1 -1
  4. data/.gitignore +20 -2
  5. data/.hound.yml +2 -1
  6. data/.prettierrc +6 -0
  7. data/.rubocop.yml +31 -10
  8. data/CHANGELOG.md +89 -3
  9. data/Gemfile +24 -22
  10. data/README.md +31 -19
  11. data/Rakefile +10 -8
  12. data/alchemy_cms.gemspec +5 -4
  13. data/app/assets/javascripts/alchemy/admin.js +1 -5
  14. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +2 -1
  15. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +0 -2
  16. data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +17 -17
  17. data/app/assets/javascripts/alchemy/node_select.js +39 -0
  18. data/app/assets/javascripts/alchemy/templates/index.js +1 -0
  19. data/app/assets/javascripts/alchemy/templates/node.hbs +16 -0
  20. data/app/assets/stylesheets/alchemy/admin.scss +3 -2
  21. data/app/assets/stylesheets/alchemy/base.scss +0 -1
  22. data/app/assets/stylesheets/alchemy/elements.scss +1 -1
  23. data/app/assets/stylesheets/alchemy/forms.scss +5 -0
  24. data/app/assets/stylesheets/alchemy/node-select.scss +43 -0
  25. data/app/assets/stylesheets/alchemy/nodes.scss +1 -1
  26. data/app/assets/stylesheets/alchemy/sitemap.scss +5 -1
  27. data/app/assets/stylesheets/alchemy/tables.scss +1 -24
  28. data/app/controllers/alchemy/admin/attachments_controller.rb +8 -7
  29. data/app/controllers/alchemy/admin/base_controller.rb +13 -33
  30. data/app/controllers/alchemy/admin/clipboard_controller.rb +5 -4
  31. data/app/controllers/alchemy/admin/contents_controller.rb +1 -2
  32. data/app/controllers/alchemy/admin/dashboard_controller.rb +10 -9
  33. data/app/controllers/alchemy/admin/elements_controller.rb +20 -20
  34. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +12 -14
  35. data/app/controllers/alchemy/admin/languages_controller.rb +35 -2
  36. data/app/controllers/alchemy/admin/layoutpages_controller.rb +5 -2
  37. data/app/controllers/alchemy/admin/nodes_controller.rb +5 -4
  38. data/app/controllers/alchemy/admin/pages_controller.rb +50 -62
  39. data/app/controllers/alchemy/admin/pictures_controller.rb +16 -16
  40. data/app/controllers/alchemy/admin/resources_controller.rb +21 -13
  41. data/app/controllers/alchemy/admin/sites_controller.rb +18 -0
  42. data/app/controllers/alchemy/admin/styleguide_controller.rb +1 -0
  43. data/app/controllers/alchemy/admin/tags_controller.rb +5 -3
  44. data/app/controllers/alchemy/admin/trash_controller.rb +6 -6
  45. data/app/controllers/alchemy/api/base_controller.rb +2 -2
  46. data/app/controllers/alchemy/api/contents_controller.rb +4 -4
  47. data/app/controllers/alchemy/api/elements_controller.rb +8 -8
  48. data/app/controllers/alchemy/api/nodes_controller.rb +37 -1
  49. data/app/controllers/alchemy/api/pages_controller.rb +14 -23
  50. data/app/controllers/alchemy/attachments_controller.rb +5 -5
  51. data/app/controllers/alchemy/base_controller.rb +10 -9
  52. data/app/controllers/alchemy/messages_controller.rb +16 -23
  53. data/app/controllers/alchemy/pages_controller.rb +13 -11
  54. data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +3 -2
  55. data/app/controllers/concerns/alchemy/admin/current_language.rb +23 -0
  56. data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +5 -5
  57. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +4 -4
  58. data/app/controllers/concerns/alchemy/page_redirects.rb +2 -9
  59. data/app/controllers/concerns/alchemy/site_redirects.rb +2 -2
  60. data/app/decorators/alchemy/element_editor.rb +39 -0
  61. data/app/helpers/alchemy/admin/attachments_helper.rb +6 -6
  62. data/app/helpers/alchemy/admin/base_helper.rb +36 -35
  63. data/app/helpers/alchemy/admin/contents_helper.rb +3 -3
  64. data/app/helpers/alchemy/admin/elements_helper.rb +3 -88
  65. data/app/helpers/alchemy/admin/essences_helper.rb +8 -117
  66. data/app/helpers/alchemy/admin/form_helper.rb +1 -1
  67. data/app/helpers/alchemy/admin/navigation_helper.rb +24 -23
  68. data/app/helpers/alchemy/admin/pages_helper.rb +4 -4
  69. data/app/helpers/alchemy/admin/pictures_helper.rb +3 -3
  70. data/app/helpers/alchemy/admin/tags_helper.rb +8 -7
  71. data/app/helpers/alchemy/base_helper.rb +13 -8
  72. data/app/helpers/alchemy/elements_block_helper.rb +2 -31
  73. data/app/helpers/alchemy/elements_helper.rb +12 -58
  74. data/app/helpers/alchemy/pages_helper.rb +24 -174
  75. data/app/helpers/alchemy/url_helper.rb +2 -1
  76. data/app/mailers/alchemy/base_mailer.rb +1 -1
  77. data/app/mailers/alchemy/messages_mailer.rb +1 -1
  78. data/app/models/alchemy/attachment.rb +20 -18
  79. data/app/models/alchemy/base_record.rb +2 -5
  80. data/app/models/alchemy/content.rb +33 -38
  81. data/app/models/alchemy/content/factory.rb +24 -31
  82. data/app/models/alchemy/element.rb +45 -53
  83. data/app/models/alchemy/element/definitions.rb +4 -4
  84. data/app/models/alchemy/element/element_contents.rb +9 -6
  85. data/app/models/alchemy/element/element_essences.rb +4 -3
  86. data/app/models/alchemy/element/presenters.rb +3 -2
  87. data/app/models/alchemy/element_to_page.rb +1 -1
  88. data/app/models/alchemy/essence_boolean.rb +1 -3
  89. data/app/models/alchemy/essence_date.rb +2 -3
  90. data/app/models/alchemy/essence_file.rb +4 -4
  91. data/app/models/alchemy/essence_html.rb +1 -3
  92. data/app/models/alchemy/essence_link.rb +1 -3
  93. data/app/models/alchemy/essence_node.rb +18 -0
  94. data/app/models/alchemy/essence_page.rb +3 -16
  95. data/app/models/alchemy/essence_picture.rb +17 -16
  96. data/app/models/alchemy/essence_picture_view.rb +7 -6
  97. data/app/models/alchemy/essence_richtext.rb +1 -3
  98. data/app/models/alchemy/essence_select.rb +1 -3
  99. data/app/models/alchemy/essence_text.rb +0 -2
  100. data/app/models/alchemy/folded_page.rb +1 -0
  101. data/app/models/alchemy/language.rb +21 -35
  102. data/app/models/alchemy/language/code.rb +4 -4
  103. data/app/models/alchemy/legacy_page_url.rb +1 -1
  104. data/app/models/alchemy/message.rb +3 -3
  105. data/app/models/alchemy/node.rb +27 -4
  106. data/app/models/alchemy/page.rb +46 -127
  107. data/app/models/alchemy/page/fixed_attributes.rb +3 -2
  108. data/app/models/alchemy/page/page_elements.rb +35 -44
  109. data/app/models/alchemy/page/page_naming.rb +20 -70
  110. data/app/models/alchemy/page/page_natures.rb +7 -34
  111. data/app/models/alchemy/page/page_scopes.rb +23 -29
  112. data/app/models/alchemy/page/url_path.rb +0 -2
  113. data/app/models/alchemy/picture.rb +18 -27
  114. data/app/models/alchemy/picture/transformations.rb +9 -7
  115. data/app/models/alchemy/picture/url.rb +5 -5
  116. data/app/models/alchemy/site.rb +6 -36
  117. data/app/models/alchemy/site/layout.rb +2 -2
  118. data/app/models/concerns/alchemy/touch_elements.rb +24 -0
  119. data/app/serializers/alchemy/content_serializer.rb +0 -3
  120. data/app/serializers/alchemy/essence_boolean_serializer.rb +3 -3
  121. data/app/serializers/alchemy/essence_date_serializer.rb +3 -3
  122. data/app/serializers/alchemy/essence_file_serializer.rb +4 -2
  123. data/app/serializers/alchemy/essence_html_serializer.rb +3 -3
  124. data/app/serializers/alchemy/essence_link_serializer.rb +3 -3
  125. data/app/serializers/alchemy/essence_picture_serializer.rb +5 -4
  126. data/app/serializers/alchemy/essence_richtext_serializer.rb +3 -3
  127. data/app/serializers/alchemy/essence_select_serializer.rb +3 -3
  128. data/app/serializers/alchemy/essence_text_serializer.rb +5 -4
  129. data/app/serializers/alchemy/node_serializer.rb +2 -0
  130. data/app/serializers/alchemy/page_tree_serializer.rb +9 -13
  131. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -2
  132. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +1 -2
  133. data/app/views/alchemy/admin/attachments/_files_list.html.erb +4 -4
  134. data/app/views/alchemy/admin/contents/create.js.erb +1 -3
  135. data/app/views/alchemy/admin/elements/_element.html.erb +9 -18
  136. data/app/views/alchemy/admin/elements/create.js.erb +1 -1
  137. data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
  138. data/app/views/alchemy/admin/elements/index.html.erb +3 -3
  139. data/app/views/alchemy/admin/essence_files/assign.js.erb +1 -6
  140. data/app/views/alchemy/admin/essence_files/edit.html.erb +1 -1
  141. data/app/views/alchemy/admin/essence_pictures/assign.js.erb +1 -7
  142. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -1
  143. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +7 -7
  144. data/app/views/alchemy/admin/essence_pictures/update.js.erb +1 -1
  145. data/app/views/alchemy/admin/languages/_form.html.erb +5 -5
  146. data/app/views/alchemy/admin/languages/_table.html.erb +3 -3
  147. data/app/views/alchemy/admin/languages/edit.html.erb +1 -0
  148. data/app/views/alchemy/admin/languages/index.html.erb +23 -4
  149. data/app/views/alchemy/admin/languages/new.html.erb +1 -0
  150. data/app/views/alchemy/admin/layoutpages/index.html.erb +3 -3
  151. data/app/views/alchemy/admin/nodes/_form.html.erb +18 -15
  152. data/app/views/alchemy/admin/nodes/_node.html.erb +1 -5
  153. data/app/views/alchemy/admin/nodes/index.html.erb +3 -4
  154. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +0 -8
  155. data/app/views/alchemy/admin/pages/_form.html.erb +0 -1
  156. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -0
  157. data/app/views/alchemy/admin/pages/_page.html.erb +11 -19
  158. data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -4
  159. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  160. data/app/views/alchemy/admin/pages/info.html.erb +0 -9
  161. data/app/views/alchemy/admin/pages/unlock.js.erb +13 -6
  162. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +0 -2
  163. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -5
  164. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
  165. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -2
  166. data/app/views/alchemy/admin/resources/_resource.html.erb +1 -1
  167. data/app/views/alchemy/admin/resources/_table.html.erb +2 -2
  168. data/app/views/alchemy/admin/sites/_form.html.erb +8 -0
  169. data/app/views/alchemy/admin/sites/edit.html.erb +1 -0
  170. data/app/views/alchemy/admin/sites/index.html.erb +21 -9
  171. data/app/views/alchemy/admin/sites/new.html.erb +1 -0
  172. data/app/views/alchemy/admin/tags/index.html.erb +2 -2
  173. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +10 -12
  174. data/app/views/alchemy/essences/_essence_date_editor.html.erb +11 -8
  175. data/app/views/alchemy/essences/_essence_file_editor.html.erb +16 -17
  176. data/app/views/alchemy/essences/_essence_html_editor.html.erb +8 -5
  177. data/app/views/alchemy/essences/_essence_link_editor.html.erb +18 -15
  178. data/app/views/alchemy/essences/_essence_node_editor.html.erb +27 -0
  179. data/app/views/alchemy/essences/_essence_node_view.html.erb +1 -0
  180. data/app/views/alchemy/essences/_essence_page_editor.html.erb +14 -11
  181. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +22 -20
  182. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +10 -7
  183. data/app/views/alchemy/essences/_essence_select_editor.html.erb +12 -16
  184. data/app/views/alchemy/essences/_essence_text_editor.html.erb +18 -17
  185. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +6 -11
  186. data/app/views/alchemy/pages/show.rss.builder +3 -2
  187. data/app/views/layouts/alchemy/admin.html.erb +1 -0
  188. data/babel.config.js +12 -0
  189. data/bin/rails +5 -4
  190. data/config/alchemy/config.yml +15 -18
  191. data/config/brakeman.ignore +1 -1
  192. data/config/initializers/assets.rb +2 -1
  193. data/config/initializers/dragonfly.rb +2 -1
  194. data/config/initializers/mime_types.rb +1 -0
  195. data/config/initializers/mini_profiler.rb +3 -2
  196. data/config/initializers/simple_form.rb +6 -6
  197. data/config/locales/alchemy.en.yml +23 -8
  198. data/config/routes.rb +25 -24
  199. data/config/spring.rb +3 -2
  200. data/db/migrate/20200226213334_alchemy_four_point_four.rb +313 -0
  201. data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +11 -0
  202. data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +28 -0
  203. data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +8 -0
  204. data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +27 -0
  205. data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +6 -0
  206. data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +24 -0
  207. data/lib/alchemy/admin/locale.rb +3 -1
  208. data/lib/alchemy/admin/preview_url.rb +64 -0
  209. data/lib/alchemy/auth_accessors.rb +8 -7
  210. data/lib/alchemy/cache_digests/template_tracker.rb +5 -4
  211. data/lib/alchemy/config.rb +1 -5
  212. data/lib/alchemy/configuration_methods.rb +3 -1
  213. data/lib/alchemy/controller_actions.rb +6 -5
  214. data/lib/alchemy/deprecation.rb +2 -1
  215. data/lib/alchemy/elements_finder.rb +5 -5
  216. data/lib/alchemy/engine.rb +23 -8
  217. data/lib/alchemy/errors.rb +0 -7
  218. data/lib/alchemy/essence.rb +17 -16
  219. data/lib/alchemy/filetypes.rb +5 -5
  220. data/lib/alchemy/forms/builder.rb +4 -4
  221. data/lib/alchemy/hints.rb +1 -1
  222. data/lib/alchemy/i18n.rb +2 -1
  223. data/lib/alchemy/modules.rb +12 -12
  224. data/lib/alchemy/name_conversions.rb +5 -5
  225. data/lib/alchemy/on_page_layout/callbacks_runner.rb +1 -0
  226. data/lib/alchemy/page_layout.rb +15 -12
  227. data/lib/alchemy/paths.rb +1 -1
  228. data/lib/alchemy/permissions.rb +7 -6
  229. data/lib/alchemy/resource.rb +23 -13
  230. data/lib/alchemy/resources_helper.rb +12 -18
  231. data/lib/alchemy/routing_constraints.rb +1 -1
  232. data/lib/alchemy/seeder.rb +42 -14
  233. data/lib/alchemy/shell.rb +13 -10
  234. data/lib/alchemy/taggable.rb +1 -0
  235. data/lib/alchemy/tasks/tidy.rb +4 -3
  236. data/lib/alchemy/test_support/config_stubbing.rb +1 -0
  237. data/lib/alchemy/test_support/essence_shared_examples.rb +72 -72
  238. data/lib/alchemy/test_support/factories.rb +1 -1
  239. data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -5
  240. data/lib/alchemy/test_support/factories/content_factory.rb +6 -6
  241. data/lib/alchemy/test_support/factories/dummy_user_factory.rb +7 -7
  242. data/lib/alchemy/test_support/factories/element_factory.rb +9 -9
  243. data/lib/alchemy/test_support/factories/essence_file_factory.rb +3 -3
  244. data/lib/alchemy/test_support/factories/essence_page_factory.rb +3 -3
  245. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +4 -4
  246. data/lib/alchemy/test_support/factories/essence_text_factory.rb +3 -3
  247. data/lib/alchemy/test_support/factories/language_factory.rb +16 -14
  248. data/lib/alchemy/test_support/factories/node_factory.rb +8 -8
  249. data/lib/alchemy/test_support/factories/page_factory.rb +15 -27
  250. data/lib/alchemy/test_support/factories/picture_factory.rb +5 -5
  251. data/lib/alchemy/test_support/factories/site_factory.rb +7 -6
  252. data/lib/alchemy/test_support/integration_helpers.rb +1 -0
  253. data/lib/alchemy/test_support/shared_contexts.rb +5 -4
  254. data/lib/alchemy/test_support/shared_uploader_examples.rb +4 -3
  255. data/lib/alchemy/tinymce.rb +15 -13
  256. data/lib/alchemy/upgrader.rb +8 -7
  257. data/lib/alchemy/upgrader/five_point_zero.rb +41 -0
  258. data/lib/alchemy/upgrader/tasks/element_views_updater.rb +4 -4
  259. data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +29 -0
  260. data/lib/alchemy/version.rb +1 -1
  261. data/lib/alchemy_cms.rb +52 -50
  262. data/lib/{rails/generators → generators}/alchemy/base.rb +5 -4
  263. data/lib/{rails/generators → generators}/alchemy/elements/elements_generator.rb +13 -9
  264. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.erb +0 -0
  265. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.haml +0 -0
  266. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.slim +0 -0
  267. data/lib/{rails/generators → generators}/alchemy/essence/essence_generator.rb +15 -13
  268. data/lib/generators/alchemy/essence/templates/editor.html.erb +17 -0
  269. data/lib/{rails/generators → generators}/alchemy/essence/templates/view.html.erb +0 -0
  270. data/lib/{rails/generators → generators}/alchemy/install/files/_article.html.erb +0 -0
  271. data/lib/{rails/generators → generators}/alchemy/install/files/_standard.html.erb +0 -0
  272. data/lib/{rails/generators → generators}/alchemy/install/files/alchemy.en.yml +0 -0
  273. data/lib/generators/alchemy/install/files/alchemy_admin.js +1 -0
  274. data/lib/{rails/generators → generators}/alchemy/install/files/all.css +0 -0
  275. data/lib/{rails/generators → generators}/alchemy/install/files/all.js +0 -0
  276. data/lib/{rails/generators → generators}/alchemy/install/files/application.html.erb +0 -0
  277. data/lib/{rails/generators → generators}/alchemy/install/files/article.scss +0 -0
  278. data/lib/generators/alchemy/install/install_generator.rb +110 -0
  279. data/lib/{rails/generators → generators}/alchemy/install/templates/dragonfly.rb.tt +0 -0
  280. data/lib/{rails/generators → generators}/alchemy/install/templates/elements.yml.tt +0 -0
  281. data/lib/{rails/generators → generators}/alchemy/install/templates/menus.yml.tt +0 -0
  282. data/lib/{rails/generators → generators}/alchemy/install/templates/page_layouts.yml.tt +0 -0
  283. data/lib/{rails/generators → generators}/alchemy/menus/menus_generator.rb +2 -2
  284. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.erb +1 -4
  285. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.haml +1 -4
  286. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.slim +1 -4
  287. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.erb +1 -1
  288. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.haml +1 -1
  289. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.slim +1 -1
  290. data/lib/{rails/generators → generators}/alchemy/module/module_generator.rb +3 -2
  291. data/lib/{rails/generators → generators}/alchemy/module/templates/ability.rb.tt +0 -0
  292. data/lib/{rails/generators → generators}/alchemy/module/templates/controller.rb.tt +0 -0
  293. data/lib/{rails/generators → generators}/alchemy/module/templates/module_config.rb.tt +0 -0
  294. data/lib/{rails/generators → generators}/alchemy/page_layouts/page_layouts_generator.rb +5 -4
  295. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.erb +0 -0
  296. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.haml +0 -0
  297. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.slim +0 -0
  298. data/lib/{rails/generators → generators}/alchemy/site_layouts/site_layouts_generator.rb +4 -2
  299. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.erb +0 -0
  300. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.haml +0 -0
  301. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.slim +0 -0
  302. data/lib/{rails/generators → generators}/alchemy/views/views_generator.rb +7 -6
  303. data/lib/kaminari/scoped_pagination_url_helper.rb +1 -0
  304. data/lib/tasks/alchemy/db.rake +3 -19
  305. data/lib/tasks/alchemy/install.rake +3 -2
  306. data/lib/tasks/alchemy/tidy.rake +9 -8
  307. data/lib/tasks/alchemy/upgrade.rake +18 -116
  308. data/package.json +45 -0
  309. data/package/admin.js +14 -0
  310. data/package/src/__tests__/i18n.spec.js +70 -0
  311. data/package/src/i18n.js +48 -0
  312. data/package/src/node_tree.js +72 -0
  313. data/package/src/translations.js +32 -0
  314. data/package/src/utils/__tests__/ajax.spec.js +124 -0
  315. data/package/src/utils/__tests__/events.spec.js +38 -0
  316. data/package/src/utils/ajax.js +48 -0
  317. data/package/src/utils/events.js +16 -0
  318. data/vendor/assets/fonts/fa-regular-400.eot +0 -0
  319. data/vendor/assets/fonts/fa-regular-400.svg +798 -358
  320. data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
  321. data/vendor/assets/fonts/fa-regular-400.woff +0 -0
  322. data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
  323. data/vendor/assets/fonts/fa-solid-900.eot +0 -0
  324. data/vendor/assets/fonts/fa-solid-900.svg +4933 -1408
  325. data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
  326. data/vendor/assets/fonts/fa-solid-900.woff +0 -0
  327. data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
  328. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +1 -2
  329. data/vendor/assets/stylesheets/fontawesome/_core.scss +5 -0
  330. data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +1 -1
  331. data/vendor/assets/stylesheets/fontawesome/_icons.scss +651 -2
  332. data/vendor/assets/stylesheets/fontawesome/_mixins.scss +0 -1
  333. data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +3 -2
  334. data/vendor/assets/stylesheets/fontawesome/_stacked.scss +1 -1
  335. data/vendor/assets/stylesheets/fontawesome/_variables.scss +662 -9
  336. data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +2 -2
  337. data/vendor/assets/stylesheets/fontawesome/regular.scss +23 -0
  338. data/vendor/assets/stylesheets/fontawesome/solid.scss +24 -0
  339. metadata +110 -88
  340. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +0 -32
  341. data/app/assets/javascripts/alchemy/alchemy.node_tree.js +0 -66
  342. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +0 -29
  343. data/app/assets/javascripts/alchemy/alchemy.utils.js +0 -45
  344. data/app/helpers/alchemy/essences_helper.rb +0 -119
  345. data/app/models/concerns/alchemy/content_touching.rb +0 -23
  346. data/app/serializers/alchemy/legacy_element_serializer.rb +0 -15
  347. data/app/views/alchemy/admin/contents/_missing.html.erb +0 -17
  348. data/app/views/alchemy/admin/pages/_menu_fields.html.erb +0 -37
  349. data/app/views/alchemy/admin/pages/configure_external.html.erb +0 -32
  350. data/app/views/alchemy/elements/_editor_not_found.html.erb +0 -4
  351. data/app/views/alchemy/navigation/_image_link.html.erb +0 -14
  352. data/app/views/alchemy/navigation/_link.html.erb +0 -19
  353. data/app/views/alchemy/navigation/_renderer.html.erb +0 -29
  354. data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -363
  355. data/db/migrate/20180227224537_migrate_tags_to_gutentag.rb +0 -41
  356. data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +0 -6
  357. data/db/migrate/20191016073858_create_alchemy_essence_pages.rb +0 -8
  358. data/db/migrate/20191029212236_create_alchemy_nodes.rb +0 -24
  359. data/db/migrate/20200226081535_add_site_id_to_alchemy_nodes.rb +0 -15
  360. data/lib/alchemy/ssl_protection.rb +0 -34
  361. data/lib/alchemy/tasks/helpers.rb +0 -81
  362. data/lib/alchemy/test_support/controller_requests.rb +0 -93
  363. data/lib/alchemy/upgrader/four_point_four.rb +0 -52
  364. data/lib/alchemy/upgrader/four_point_one.rb +0 -42
  365. data/lib/alchemy/upgrader/four_point_six.rb +0 -50
  366. data/lib/alchemy/upgrader/four_point_two.rb +0 -85
  367. data/lib/alchemy/upgrader/tasks/cells_migration.rb +0 -43
  368. data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +0 -148
  369. data/lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb +0 -28
  370. data/lib/alchemy/upgrader/tasks/harden_acts_as_taggable_on_migrations.rb +0 -27
  371. data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +0 -65
  372. data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +0 -210
  373. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +0 -15
  374. data/lib/rails/generators/alchemy/install/install_generator.rb +0 -60
  375. data/lib/tasks/alchemy/convert.rake +0 -97
  376. data/vendor/assets/javascripts/sortable/Sortable.min.js +0 -2
  377. data/vendor/assets/stylesheets/fontawesome/fa-regular.scss +0 -22
  378. data/vendor/assets/stylesheets/fontawesome/fa-solid.scss +0 -23
@@ -34,7 +34,7 @@ module Alchemy
34
34
  def no_rails_route?
35
35
  return true if !%w(development test).include?(Rails.env)
36
36
 
37
- (@params['urlname'] =~ /\Arails\//).nil?
37
+ (@params["urlname"] =~ /\Arails\//).nil?
38
38
  end
39
39
  end
40
40
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "alchemy/shell"
2
3
 
3
4
  module Alchemy
@@ -23,11 +24,14 @@ module Alchemy
23
24
 
24
25
  def try_seed_pages
25
26
  return unless page_seeds_file.file?
27
+
26
28
  if Alchemy::Page.exists?
27
29
  desc "Seeding Alchemy pages"
28
30
  log "There are already pages present in your database. " \
29
31
  "Please use `rake db:reset' if you want to rebuild your database.", :skip
30
32
  else
33
+ create_default_site! unless Alchemy::Site.default
34
+ create_default_language! unless Alchemy::Language.default
31
35
  seed_pages if contentpages.present?
32
36
  seed_layoutpages if layoutpages.present?
33
37
  end
@@ -41,9 +45,8 @@ module Alchemy
41
45
 
42
46
  contentpages.each do |page|
43
47
  create_page(page, {
44
- parent: Alchemy::Page.root,
45
48
  language: Alchemy::Language.default,
46
- language_root: true
49
+ language_root: true,
47
50
  })
48
51
  end
49
52
  end
@@ -51,12 +54,8 @@ module Alchemy
51
54
  def seed_layoutpages
52
55
  desc "Seeding Alchemy layout pages from #{page_seeds_file}"
53
56
  language = Alchemy::Language.default
54
- layout_root = Alchemy::Page.find_or_create_layout_root_for(language.id)
55
57
  layoutpages.each do |page|
56
- create_page(page, {
57
- parent: layout_root,
58
- language: language
59
- })
58
+ create_page(page, { language: language })
60
59
  end
61
60
  end
62
61
 
@@ -66,7 +65,7 @@ module Alchemy
66
65
  if Alchemy.user_class.exists?
67
66
  log "There are already users present in your database. " \
68
67
  "Please use `rake db:reset' if you want to rebuild your database.", :skip
69
- return false
68
+ false
70
69
  else
71
70
  users = YAML.load_file(user_seeds_file)
72
71
  users.each do |draft|
@@ -79,7 +78,7 @@ module Alchemy
79
78
  private
80
79
 
81
80
  def page_seeds_file
82
- @_page_seeds_file ||= Rails.root.join('db', 'seeds', 'alchemy', 'pages.yml')
81
+ @_page_seeds_file ||= Rails.root.join("db", "seeds", "alchemy", "pages.yml")
83
82
  end
84
83
 
85
84
  def page_yml
@@ -87,23 +86,52 @@ module Alchemy
87
86
  end
88
87
 
89
88
  def contentpages
90
- page_yml.reject { |p| p['layoutpage'] }
89
+ page_yml.reject { |p| p["layoutpage"] }
91
90
  end
92
91
 
93
92
  def layoutpages
94
- page_yml.select { |p| p['layoutpage'] }
93
+ page_yml.select { |p| p["layoutpage"] }
95
94
  end
96
95
 
97
96
  def user_seeds_file
98
- @_user_seeds_file ||= Rails.root.join('db', 'seeds', 'alchemy', 'users.yml')
97
+ @_user_seeds_file ||= Rails.root.join("db", "seeds", "alchemy", "users.yml")
99
98
  end
100
99
 
101
100
  def create_page(draft, attributes = {})
102
- children = draft.delete('children') || []
101
+ children = draft.delete("children") || []
103
102
  page = Alchemy::Page.create!(draft.merge(attributes))
104
103
  log "Created page: #{page.name}"
105
104
  children.each do |child|
106
- create_page(child, parent: page)
105
+ create_page(child, parent: page, language: page.language)
106
+ end
107
+ end
108
+
109
+ # If no languages are present, create a default language based
110
+ # on the host app's Alchemy configuration.
111
+ def create_default_language!
112
+ default_language = Alchemy::Config.get(:default_language)
113
+ if default_language
114
+ Alchemy::Language.create!(
115
+ name: default_language["name"],
116
+ language_code: default_language["code"],
117
+ locale: default_language["code"],
118
+ frontpage_name: default_language["frontpage_name"],
119
+ page_layout: default_language["page_layout"],
120
+ public: true,
121
+ default: true,
122
+ site: Alchemy::Site.default,
123
+ )
124
+ else
125
+ raise DefaultLanguageNotFoundError
126
+ end
127
+ end
128
+
129
+ def create_default_site!
130
+ default_site = Alchemy::Config.get(:default_site)
131
+ if default_site
132
+ Alchemy::Site.create!(name: default_site["name"], host: default_site["host"])
133
+ else
134
+ raise DefaultSiteNotFoundError
107
135
  end
108
136
  end
109
137
  end
data/lib/alchemy/shell.rb CHANGED
@@ -1,10 +1,18 @@
1
- require 'thor/shell/color'
1
+ # frozen_string_literal: true
2
+ require "thor/shell/color"
2
3
 
3
4
  module Alchemy
4
5
  # Provides methods for collecting sentences and displaying them
5
6
  # in a list on the shell / log
6
7
  #
7
8
  module Shell
9
+ COLORS = {
10
+ clear: Thor::Shell::Color::CLEAR,
11
+ green: Thor::Shell::Color::GREEN,
12
+ red: Thor::Shell::Color::RED,
13
+ yellow: Thor::Shell::Color::YELLOW,
14
+ }.freeze
15
+
8
16
  def self.silence!
9
17
  @silenced = true
10
18
  end
@@ -20,11 +28,11 @@ module Alchemy
20
28
  def desc(message)
21
29
  unless Alchemy::Shell.silenced?
22
30
  puts "\n#{message}"
23
- puts "#{'-' * message.length}\n"
31
+ puts "#{"-" * message.length}\n"
24
32
  end
25
33
  end
26
34
 
27
- def todo(todo, title = '')
35
+ def todo(todo, title = "")
28
36
  add_todo [title, todo]
29
37
  end
30
38
 
@@ -56,7 +64,7 @@ module Alchemy
56
64
  todos.each_with_index do |todo, i|
57
65
  title = "\n#{i + 1}. #{todo[0]}"
58
66
  log title, :message
59
- puts '=' * title.length
67
+ puts "=" * title.length
60
68
  puts ""
61
69
  log todo[1], :message
62
70
  end
@@ -96,12 +104,7 @@ module Alchemy
96
104
  # @return [String]
97
105
  #
98
106
  def color(name)
99
- color_const = name.to_s.upcase
100
- if Thor::Shell::Color.const_defined?(color_const)
101
- "Thor::Shell::Color::#{color_const}".constantize
102
- else
103
- ""
104
- end
107
+ COLORS[name]
105
108
  end
106
109
  end
107
110
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Alchemy
2
3
  # ActsAsTaggableOn to Gutentag interface compatibility module
3
4
  # Include this module to add tagging support to your model.
@@ -1,4 +1,5 @@
1
- require 'alchemy/shell'
1
+ # frozen_string_literal: true
2
+ require "alchemy/shell"
2
3
 
3
4
  module Alchemy
4
5
  class Tidy
@@ -52,7 +53,7 @@ module Alchemy
52
53
  end
53
54
  if orphaned_elements.any?
54
55
  log "Found #{orphaned_elements.size} orphaned elements"
55
- destroy_orphaned_records(orphaned_elements, 'element')
56
+ destroy_orphaned_records(orphaned_elements, "element")
56
57
  else
57
58
  log "No orphaned elements found", :skip
58
59
  end
@@ -71,7 +72,7 @@ module Alchemy
71
72
  end
72
73
  if orphaned_contents.any?
73
74
  log "Found #{orphaned_contents.size} orphaned contents"
74
- destroy_orphaned_records(orphaned_contents, 'content')
75
+ destroy_orphaned_records(orphaned_contents, "content")
75
76
  else
76
77
  log "No orphaned contents found", :skip
77
78
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Alchemy
2
3
  module TestSupport
3
4
  # Allows you to stub the Alchemy configuration in your specs
@@ -1,36 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'shoulda-matchers'
4
- require 'alchemy/test_support/factories/page_factory'
5
- require 'alchemy/test_support/factories/element_factory'
6
- require 'alchemy/test_support/factories/content_factory'
3
+ require "shoulda-matchers"
4
+ require "alchemy/test_support/factories/page_factory"
5
+ require "alchemy/test_support/factories/element_factory"
6
+ require "alchemy/test_support/factories/content_factory"
7
7
 
8
8
  RSpec.shared_examples_for "an essence" do
9
9
  let(:element) { Alchemy::Element.new }
10
- let(:content) { Alchemy::Content.new(name: 'foo') }
11
- let(:content_definition) { {'name' => 'foo'} }
10
+ let(:content) { Alchemy::Content.new(name: "foo") }
11
+ let(:content_definition) { { "name" => "foo" } }
12
12
 
13
- describe 'eager loading' do
13
+ describe "eager loading" do
14
14
  before do
15
15
  2.times { described_class.create! }
16
16
  end
17
17
 
18
- it 'does not throw error if eager loaded' do
18
+ it "does not throw error if eager loaded" do
19
19
  expect {
20
20
  described_class.all.includes(:ingredient_association).to_a
21
21
  }.to_not raise_error
22
22
  end
23
23
  end
24
24
 
25
- it "touches the content after update" do
25
+ it "touches the element after save" do
26
26
  element = FactoryBot.create(:alchemy_element)
27
27
  content = FactoryBot.create(:alchemy_content, element: element, essence: essence, essence_type: essence.class.name)
28
28
 
29
- content.update_column(:updated_at, 3.days.ago)
29
+ element.update_column(:updated_at, 3.days.ago)
30
30
  content.essence.update(essence.ingredient_column.to_sym => ingredient_value)
31
31
 
32
- content.reload
33
- expect(content.updated_at).to be_within(3.seconds).of(Time.current)
32
+ element.reload
33
+ expect(element.updated_at).to be_within(3.seconds).of(Time.current)
34
34
  end
35
35
 
36
36
  it "should have correct partial path" do
@@ -38,28 +38,28 @@ RSpec.shared_examples_for "an essence" do
38
38
  expect(essence.to_partial_path).to eq("alchemy/essences/#{underscored_essence}_view")
39
39
  end
40
40
 
41
- describe '#definition' do
41
+ describe "#definition" do
42
42
  subject { essence.definition }
43
43
 
44
- context 'without element' do
44
+ context "without element" do
45
45
  it { is_expected.to eq({}) }
46
46
  end
47
47
 
48
- context 'with element' do
48
+ context "with element" do
49
49
  before do
50
50
  expect(essence).to receive(:element).at_least(:once).and_return(element)
51
51
  end
52
52
 
53
- context 'but without content definitions' do
53
+ context "but without content definitions" do
54
54
  it { is_expected.to eq({}) }
55
55
  end
56
56
 
57
- context 'and content definitions' do
57
+ context "and content definitions" do
58
58
  before do
59
59
  allow(essence).to receive(:content).and_return(content)
60
60
  end
61
61
 
62
- context 'containing the content name' do
62
+ context "containing the content name" do
63
63
  before do
64
64
  expect(element).to receive(:content_definitions).at_least(:once).and_return([content_definition])
65
65
  end
@@ -69,7 +69,7 @@ RSpec.shared_examples_for "an essence" do
69
69
  end
70
70
  end
71
71
 
72
- context 'not containing the content name' do
72
+ context "not containing the content name" do
73
73
  before do
74
74
  expect(element).to receive(:content_definitions).at_least(:once).and_return([])
75
75
  end
@@ -80,200 +80,200 @@ RSpec.shared_examples_for "an essence" do
80
80
  end
81
81
  end
82
82
 
83
- describe '#ingredient=' do
84
- it 'should set the value to ingredient column' do
83
+ describe "#ingredient=" do
84
+ it "should set the value to ingredient column" do
85
85
  essence.ingredient = ingredient_value
86
86
  expect(essence.ingredient).to eq ingredient_value
87
87
  end
88
88
  end
89
89
 
90
- describe 'validations' do
91
- context 'without essence definition in elements.yml' do
92
- it 'should return an empty array' do
90
+ describe "validations" do
91
+ context "without essence definition in elements.yml" do
92
+ it "should return an empty array" do
93
93
  allow(essence).to receive(:definition).and_return nil
94
94
  expect(essence.validations).to eq([])
95
95
  end
96
96
  end
97
97
 
98
- context 'without validations defined in essence definition in elements.yml' do
99
- it 'should return an empty array' do
100
- allow(essence).to receive(:definition).and_return({name: 'test', type: 'EssenceText'})
98
+ context "without validations defined in essence definition in elements.yml" do
99
+ it "should return an empty array" do
100
+ allow(essence).to receive(:definition).and_return({ name: "test", type: "EssenceText" })
101
101
  expect(essence.validations).to eq([])
102
102
  end
103
103
  end
104
104
 
105
- describe 'presence' do
106
- context 'with string given as validation type' do
105
+ describe "presence" do
106
+ context "with string given as validation type" do
107
107
  before do
108
- allow(essence).to receive(:definition).and_return({'validate' => ['presence']})
108
+ allow(essence).to receive(:definition).and_return({ "validate" => ["presence"] })
109
109
  end
110
110
 
111
- context 'when the ingredient column is empty' do
111
+ context "when the ingredient column is empty" do
112
112
  before do
113
113
  essence.update(essence.ingredient_column.to_sym => nil)
114
114
  end
115
115
 
116
- it 'should not be valid' do
116
+ it "should not be valid" do
117
117
  expect(essence).to_not be_valid
118
118
  end
119
119
  end
120
120
 
121
- context 'when the ingredient column is not nil' do
121
+ context "when the ingredient column is not nil" do
122
122
  before do
123
123
  essence.update(essence.ingredient_column.to_sym => ingredient_value)
124
124
  end
125
125
 
126
- it 'should be valid' do
126
+ it "should be valid" do
127
127
  expect(essence).to be_valid
128
128
  end
129
129
  end
130
130
  end
131
131
 
132
- context 'with hash given as validation type' do
133
- context 'where the value is true' do
132
+ context "with hash given as validation type" do
133
+ context "where the value is true" do
134
134
  before do
135
- allow(essence).to receive(:definition).and_return({'validate' => [{'presence' => true}]})
135
+ allow(essence).to receive(:definition).and_return({ "validate" => [{ "presence" => true }] })
136
136
  end
137
137
 
138
- context 'when the ingredient column is empty' do
138
+ context "when the ingredient column is empty" do
139
139
  before do
140
140
  essence.update(essence.ingredient_column.to_sym => nil)
141
141
  end
142
142
 
143
- it 'should not be valid' do
143
+ it "should not be valid" do
144
144
  expect(essence).to_not be_valid
145
145
  end
146
146
  end
147
147
 
148
- context 'when the ingredient column is not nil' do
148
+ context "when the ingredient column is not nil" do
149
149
  before do
150
150
  essence.update(essence.ingredient_column.to_sym => ingredient_value)
151
151
  end
152
152
 
153
- it 'should be valid' do
153
+ it "should be valid" do
154
154
  expect(essence).to be_valid
155
155
  end
156
156
  end
157
157
  end
158
158
 
159
- context 'where the value is false' do
159
+ context "where the value is false" do
160
160
  before do
161
- allow(essence).to receive(:definition).and_return({'validate' => [{'presence' => false}]})
161
+ allow(essence).to receive(:definition).and_return({ "validate" => [{ "presence" => false }] })
162
162
  end
163
163
 
164
- it 'should be valid' do
164
+ it "should be valid" do
165
165
  expect(essence).to be_valid
166
166
  end
167
167
  end
168
168
  end
169
169
  end
170
170
 
171
- describe 'uniqueness' do
171
+ describe "uniqueness" do
172
172
  before do
173
- allow(essence).to receive(:element).and_return(FactoryBot.build_stubbed(:alchemy_element))
173
+ allow(essence).to receive(:element).and_return(FactoryBot.create(:alchemy_element))
174
174
  essence.update(essence.ingredient_column.to_sym => ingredient_value)
175
175
  end
176
176
 
177
- context 'with string given as validation type' do
177
+ context "with string given as validation type" do
178
178
  before do
179
- expect(essence).to receive(:definition).at_least(:once).and_return({'validate' => ['uniqueness']})
179
+ expect(essence).to receive(:definition).at_least(:once).and_return({ "validate" => ["uniqueness"] })
180
180
  end
181
181
 
182
- context 'when a duplicate exists' do
182
+ context "when a duplicate exists" do
183
183
  before do
184
184
  allow(essence).to receive(:duplicates).and_return([essence.dup])
185
185
  end
186
186
 
187
- it 'should not be valid' do
187
+ it "should not be valid" do
188
188
  expect(essence).to_not be_valid
189
189
  end
190
190
 
191
- context 'when validated essence is not public' do
191
+ context "when validated essence is not public" do
192
192
  before do
193
193
  expect(essence).to receive(:public?).and_return(false)
194
194
  end
195
195
 
196
- it 'should be valid' do
196
+ it "should be valid" do
197
197
  expect(essence).to be_valid
198
198
  end
199
199
  end
200
200
  end
201
201
 
202
- context 'when no duplicate exists' do
202
+ context "when no duplicate exists" do
203
203
  before do
204
204
  expect(essence).to receive(:duplicates).and_return([])
205
205
  end
206
206
 
207
- it 'should be valid' do
207
+ it "should be valid" do
208
208
  expect(essence).to be_valid
209
209
  end
210
210
  end
211
211
  end
212
212
 
213
- context 'with hash given as validation type' do
214
- context 'where the value is true' do
213
+ context "with hash given as validation type" do
214
+ context "where the value is true" do
215
215
  before do
216
- expect(essence).to receive(:definition).at_least(:once).and_return({'validate' => [{'uniqueness' => true}]})
216
+ expect(essence).to receive(:definition).at_least(:once).and_return({ "validate" => [{ "uniqueness" => true }] })
217
217
  end
218
218
 
219
- context 'when a duplicate exists' do
219
+ context "when a duplicate exists" do
220
220
  before do
221
221
  allow(essence).to receive(:duplicates).and_return([essence.dup])
222
222
  end
223
223
 
224
- it 'should not be valid' do
224
+ it "should not be valid" do
225
225
  expect(essence).to_not be_valid
226
226
  end
227
227
 
228
- context 'when validated essence is not public' do
228
+ context "when validated essence is not public" do
229
229
  before do
230
230
  expect(essence).to receive(:public?).and_return(false)
231
231
  end
232
232
 
233
- it 'should be valid' do
233
+ it "should be valid" do
234
234
  expect(essence).to be_valid
235
235
  end
236
236
  end
237
237
  end
238
238
 
239
- context 'when no duplicate exists' do
239
+ context "when no duplicate exists" do
240
240
  before do
241
241
  expect(essence).to receive(:duplicates).and_return([])
242
242
  end
243
243
 
244
- it 'should be valid' do
244
+ it "should be valid" do
245
245
  expect(essence).to be_valid
246
246
  end
247
247
  end
248
248
  end
249
249
 
250
- context 'where the value is false' do
250
+ context "where the value is false" do
251
251
  before do
252
- allow(essence).to receive(:definition).and_return({'validate' => [{'uniqueness' => false}]})
252
+ allow(essence).to receive(:definition).and_return({ "validate" => [{ "uniqueness" => false }] })
253
253
  end
254
254
 
255
- it 'should be valid' do
255
+ it "should be valid" do
256
256
  expect(essence).to be_valid
257
257
  end
258
258
  end
259
259
  end
260
260
  end
261
261
 
262
- describe '#acts_as_essence?' do
263
- it 'should return true' do
262
+ describe "#acts_as_essence?" do
263
+ it "should return true" do
264
264
  expect(essence.acts_as_essence?).to be_truthy
265
265
  end
266
266
  end
267
267
  end
268
268
 
269
- context 'delegations' do
269
+ context "delegations" do
270
270
  it { should delegate_method(:restricted?).to(:page) }
271
271
  it { should delegate_method(:trashed?).to(:element) }
272
- it { should delegate_method(:public?).to(:element) }
272
+ it { should delegate_method(:public?).to(:element) }
273
273
  end
274
274
 
275
- describe 'essence relations' do
276
- let(:page) { FactoryBot.create(:alchemy_page, :restricted) }
275
+ describe "essence relations" do
276
+ let(:page) { FactoryBot.create(:alchemy_page, :restricted) }
277
277
  let(:element) { FactoryBot.create(:alchemy_element) }
278
278
 
279
279
  it "registers itself on page as essence relation" do