alchemy_cms 6.1.5 → 7.0.0.pre.b

Sign up to get free protection for your applications and to get access to all the features.
Files changed (363) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/brakeman-analysis.yml +2 -2
  3. data/.github/workflows/ci.yml +7 -10
  4. data/.github/workflows/lint.yml +17 -0
  5. data/.gitignore +1 -6
  6. data/.hound.yml +2 -3
  7. data/.rubocop.yml +4 -350
  8. data/.standard.yml +3 -0
  9. data/CHANGELOG.md +49 -19
  10. data/Gemfile +4 -2
  11. data/README.md +7 -9
  12. data/Rakefile +12 -7
  13. data/alchemy_cms.gemspec +3 -3
  14. data/app/assets/javascripts/alchemy/admin.js +0 -1
  15. data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +1 -1
  16. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +18 -32
  17. data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +2 -2
  18. data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +2 -2
  19. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +33 -30
  20. data/app/assets/stylesheets/alchemy/elements.scss +16 -35
  21. data/app/assets/stylesheets/alchemy/forms.scss +0 -4
  22. data/app/assets/stylesheets/alchemy/node-select.scss +2 -2
  23. data/app/components/alchemy/ingredients/audio_view.rb +37 -0
  24. data/app/components/alchemy/ingredients/base_view.rb +38 -0
  25. data/app/components/alchemy/ingredients/boolean_view.rb +13 -0
  26. data/app/components/alchemy/ingredients/datetime_view.rb +22 -0
  27. data/app/components/alchemy/ingredients/file_view.rb +40 -0
  28. data/app/components/alchemy/ingredients/headline_view.rb +20 -0
  29. data/app/components/alchemy/ingredients/html_view.rb +9 -0
  30. data/app/components/alchemy/ingredients/link_view.rb +25 -0
  31. data/app/components/alchemy/ingredients/node_view.rb +11 -0
  32. data/app/components/alchemy/ingredients/page_view.rb +15 -0
  33. data/app/components/alchemy/ingredients/picture_view.rb +108 -0
  34. data/app/components/alchemy/ingredients/richtext_view.rb +22 -0
  35. data/app/components/alchemy/ingredients/select_view.rb +6 -0
  36. data/app/components/alchemy/ingredients/text_view.rb +41 -0
  37. data/app/components/alchemy/ingredients/video_view.rb +39 -0
  38. data/app/controllers/alchemy/admin/attachments_controller.rb +3 -4
  39. data/app/controllers/alchemy/admin/base_controller.rb +7 -7
  40. data/app/controllers/alchemy/admin/clipboard_controller.rb +2 -2
  41. data/app/controllers/alchemy/admin/elements_controller.rb +33 -43
  42. data/app/controllers/alchemy/admin/languages_controller.rb +1 -1
  43. data/app/controllers/alchemy/admin/nodes_controller.rb +2 -2
  44. data/app/controllers/alchemy/admin/pages_controller.rb +11 -11
  45. data/app/controllers/alchemy/admin/pictures_controller.rb +15 -15
  46. data/app/controllers/alchemy/admin/resources_controller.rb +28 -46
  47. data/app/controllers/alchemy/admin/styleguide_controller.rb +1 -0
  48. data/app/controllers/alchemy/admin/tags_controller.rb +11 -11
  49. data/app/controllers/alchemy/api/base_controller.rb +2 -2
  50. data/app/controllers/alchemy/api/elements_controller.rb +11 -13
  51. data/app/controllers/alchemy/api/ingredients_controller.rb +1 -1
  52. data/app/controllers/alchemy/api/nodes_controller.rb +1 -1
  53. data/app/controllers/alchemy/api/pages_controller.rb +14 -12
  54. data/app/controllers/alchemy/attachments_controller.rb +3 -3
  55. data/app/controllers/alchemy/base_controller.rb +1 -1
  56. data/app/controllers/alchemy/messages_controller.rb +18 -18
  57. data/app/controllers/alchemy/pages_controller.rb +10 -16
  58. data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +1 -0
  59. data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +5 -7
  60. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +5 -5
  61. data/app/decorators/alchemy/element_editor.rb +13 -33
  62. data/app/decorators/alchemy/ingredient_editor.rb +6 -6
  63. data/app/helpers/alchemy/admin/attachments_helper.rb +1 -1
  64. data/app/helpers/alchemy/admin/base_helper.rb +21 -22
  65. data/app/helpers/alchemy/admin/elements_helper.rb +1 -3
  66. data/app/helpers/alchemy/admin/form_helper.rb +1 -1
  67. data/app/helpers/alchemy/admin/navigation_helper.rb +7 -7
  68. data/app/helpers/alchemy/admin/pages_helper.rb +2 -2
  69. data/app/helpers/alchemy/admin/tags_helper.rb +3 -3
  70. data/app/helpers/alchemy/base_helper.rb +2 -2
  71. data/app/helpers/alchemy/elements_block_helper.rb +13 -48
  72. data/app/helpers/alchemy/elements_helper.rb +15 -23
  73. data/app/helpers/alchemy/pages_helper.rb +11 -15
  74. data/app/helpers/alchemy/url_helper.rb +1 -1
  75. data/app/mailers/alchemy/messages_mailer.rb +1 -1
  76. data/app/models/alchemy/attachment.rb +12 -9
  77. data/app/models/alchemy/base_record.rb +3 -0
  78. data/app/models/alchemy/eager_loading.rb +6 -7
  79. data/app/models/alchemy/element/definitions.rb +1 -1
  80. data/app/models/alchemy/element/element_ingredients.rb +4 -11
  81. data/app/models/alchemy/element/presenters.rb +9 -25
  82. data/app/models/alchemy/element.rb +4 -19
  83. data/app/models/alchemy/elements_repository.rb +1 -1
  84. data/app/models/alchemy/image_cropper_settings.rb +2 -2
  85. data/app/models/alchemy/ingredient.rb +29 -16
  86. data/app/models/alchemy/ingredient_validator.rb +1 -1
  87. data/app/models/alchemy/ingredients/audio.rb +2 -0
  88. data/app/models/alchemy/ingredients/datetime.rb +3 -1
  89. data/app/models/alchemy/ingredients/file.rb +7 -0
  90. data/app/models/alchemy/ingredients/headline.rb +6 -0
  91. data/app/models/alchemy/ingredients/link.rb +2 -0
  92. data/app/models/alchemy/ingredients/node.rb +2 -0
  93. data/app/models/alchemy/ingredients/page.rb +2 -0
  94. data/app/models/alchemy/ingredients/picture.rb +29 -0
  95. data/app/models/alchemy/ingredients/richtext.rb +17 -8
  96. data/app/models/alchemy/ingredients/select.rb +1 -0
  97. data/app/models/alchemy/ingredients/text.rb +8 -0
  98. data/app/models/alchemy/ingredients/video.rb +2 -0
  99. data/app/models/alchemy/language/code.rb +1 -1
  100. data/app/models/alchemy/language.rb +4 -4
  101. data/app/models/alchemy/legacy_page_url.rb +1 -1
  102. data/app/models/alchemy/node.rb +11 -8
  103. data/app/models/alchemy/page/page_elements.rb +19 -40
  104. data/app/models/alchemy/page/page_layouts.rb +0 -14
  105. data/app/models/alchemy/page/page_naming.rb +4 -4
  106. data/app/models/alchemy/page/page_natures.rb +1 -11
  107. data/app/models/alchemy/page/page_scopes.rb +5 -5
  108. data/app/models/alchemy/page.rb +11 -19
  109. data/app/models/alchemy/picture/calculations.rb +2 -2
  110. data/app/models/alchemy/picture/transformations.rb +2 -32
  111. data/app/models/alchemy/picture/url.rb +5 -5
  112. data/app/models/alchemy/picture.rb +22 -20
  113. data/app/models/alchemy/picture_thumb/create.rb +7 -18
  114. data/app/models/alchemy/picture_thumb/file_store.rb +33 -0
  115. data/app/models/alchemy/picture_thumb.rb +11 -11
  116. data/app/models/alchemy/picture_variant.rb +2 -3
  117. data/app/models/alchemy/tag.rb +8 -0
  118. data/app/models/concerns/alchemy/picture_thumbnails.rb +8 -8
  119. data/app/serializers/alchemy/base_serializer.rb +1 -1
  120. data/app/serializers/alchemy/element_serializer.rb +1 -6
  121. data/app/serializers/alchemy/page_tree_serializer.rb +7 -7
  122. data/app/services/alchemy/delete_elements.rb +1 -7
  123. data/app/services/alchemy/duplicate_element.rb +2 -7
  124. data/app/services/alchemy/tag_validations.rb +1 -1
  125. data/app/views/alchemy/admin/elements/_element.html.erb +8 -22
  126. data/app/views/alchemy/admin/elements/create.js.erb +1 -1
  127. data/app/views/alchemy/admin/elements/fold.js.erb +2 -2
  128. data/app/views/alchemy/admin/elements/order.js.erb +1 -1
  129. data/app/views/alchemy/admin/elements/update.js.erb +1 -2
  130. data/app/views/alchemy/admin/pages/_external_link.html.erb +2 -2
  131. data/app/views/alchemy/admin/pages/_file_link.html.erb +2 -2
  132. data/app/views/alchemy/admin/pages/_internal_link.html.erb +2 -2
  133. data/app/views/alchemy/admin/pages/edit.html.erb +1 -4
  134. data/app/views/alchemy/admin/pages/update.js.erb +10 -4
  135. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -3
  136. data/app/views/alchemy/admin/pictures/_infos.html.erb +4 -6
  137. data/app/views/alchemy/ingredients/_audio_view.html.erb +1 -14
  138. data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
  139. data/app/views/alchemy/ingredients/_boolean_view.html.erb +1 -1
  140. data/app/views/alchemy/ingredients/_datetime_view.html.erb +3 -9
  141. data/app/views/alchemy/ingredients/_file_view.html.erb +3 -16
  142. data/app/views/alchemy/ingredients/_headline_editor.html.erb +1 -1
  143. data/app/views/alchemy/ingredients/_headline_view.html.erb +4 -10
  144. data/app/views/alchemy/ingredients/_html_editor.html.erb +1 -1
  145. data/app/views/alchemy/ingredients/_html_view.html.erb +1 -1
  146. data/app/views/alchemy/ingredients/_link_view.html.erb +4 -9
  147. data/app/views/alchemy/ingredients/_node_editor.html.erb +1 -1
  148. data/app/views/alchemy/ingredients/_node_view.html.erb +1 -1
  149. data/app/views/alchemy/ingredients/_page_view.html.erb +1 -4
  150. data/app/views/alchemy/ingredients/_picture_editor.html.erb +4 -4
  151. data/app/views/alchemy/ingredients/_picture_view.html.erb +4 -5
  152. data/app/views/alchemy/ingredients/_richtext_editor.html.erb +11 -2
  153. data/app/views/alchemy/ingredients/_richtext_view.html.erb +3 -3
  154. data/app/views/alchemy/ingredients/_select_editor.html.erb +2 -2
  155. data/app/views/alchemy/ingredients/_select_view.html.erb +1 -1
  156. data/app/views/alchemy/ingredients/_text_editor.html.erb +1 -1
  157. data/app/views/alchemy/ingredients/_text_view.html.erb +3 -19
  158. data/app/views/alchemy/ingredients/_video_view.html.erb +3 -18
  159. data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +4 -3
  160. data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +1 -0
  161. data/app/views/alchemy/pages/_meta_data.html.erb +0 -1
  162. data/app/views/layouts/alchemy/admin.html.erb +10 -8
  163. data/bin/setup +37 -0
  164. data/bin/start +17 -0
  165. data/config/alchemy/config.yml +6 -6
  166. data/config/brakeman.ignore +56 -57
  167. data/config/initializers/assets.rb +1 -0
  168. data/config/initializers/dragonfly.rb +1 -0
  169. data/config/initializers/mime_types.rb +1 -0
  170. data/config/initializers/mini_profiler.rb +1 -0
  171. data/config/initializers/simple_form.rb +3 -2
  172. data/config/locales/alchemy.en.yml +98 -112
  173. data/config/routes.rb +22 -36
  174. data/config/spring.rb +1 -0
  175. data/db/migrate/20230121212637_alchemy_six_point_one.rb +248 -0
  176. data/db/migrate/20230505132743_add_indexes_to_alchemy_pictures.rb +6 -0
  177. data/lib/alchemy/admin/locale.rb +3 -3
  178. data/lib/alchemy/admin/preview_url.rb +2 -2
  179. data/lib/alchemy/auth_accessors.rb +1 -1
  180. data/lib/alchemy/cache_digests/template_tracker.rb +6 -7
  181. data/lib/alchemy/config.rb +3 -3
  182. data/lib/alchemy/controller_actions.rb +4 -4
  183. data/lib/alchemy/deprecation.rb +2 -1
  184. data/lib/alchemy/dragonfly/processors/thumbnail.rb +1 -1
  185. data/lib/alchemy/element_definition.rb +2 -2
  186. data/lib/alchemy/engine.rb +2 -1
  187. data/lib/alchemy/errors.rb +0 -11
  188. data/lib/alchemy/filetypes.rb +7 -7
  189. data/lib/alchemy/forms/builder.rb +4 -4
  190. data/lib/alchemy/hints.rb +10 -10
  191. data/lib/alchemy/i18n.rb +6 -4
  192. data/lib/alchemy/install/tasks.rb +2 -1
  193. data/lib/alchemy/name_conversions.rb +1 -1
  194. data/lib/alchemy/page_layout.rb +1 -1
  195. data/lib/alchemy/permissions.rb +5 -17
  196. data/lib/alchemy/resource.rb +10 -10
  197. data/lib/alchemy/resources_helper.rb +7 -7
  198. data/lib/alchemy/routing_constraints.rb +5 -5
  199. data/lib/alchemy/searchable_resource.rb +38 -0
  200. data/lib/alchemy/seeder.rb +4 -3
  201. data/lib/alchemy/shell.rb +2 -1
  202. data/lib/alchemy/taggable.rb +3 -2
  203. data/lib/alchemy/tasks/tidy.rb +1 -38
  204. data/lib/alchemy/test_support/capybara_helpers.rb +69 -0
  205. data/lib/alchemy/test_support/config_stubbing.rb +1 -0
  206. data/lib/alchemy/test_support/factories/element_factory.rb +2 -4
  207. data/lib/alchemy/test_support/factories/ingredient_factory.rb +1 -1
  208. data/lib/alchemy/test_support/factories/page_factory.rb +5 -3
  209. data/lib/alchemy/test_support/having_crop_action_examples.rb +9 -9
  210. data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +33 -33
  211. data/lib/alchemy/test_support/integration_helpers.rb +4 -3
  212. data/lib/alchemy/test_support/shared_contexts.rb +2 -1
  213. data/lib/alchemy/test_support/shared_dom_ids_examples.rb +10 -10
  214. data/lib/alchemy/test_support/shared_ingredient_examples.rb +13 -7
  215. data/lib/alchemy/test_support/shared_uploader_examples.rb +1 -0
  216. data/lib/alchemy/tinymce.rb +3 -43
  217. data/lib/alchemy/upgrader/seven_point_zero.rb +45 -0
  218. data/lib/alchemy/upgrader/tasks/.keep +0 -0
  219. data/lib/alchemy/upgrader.rb +9 -3
  220. data/lib/alchemy/version.rb +1 -1
  221. data/lib/alchemy.rb +0 -19
  222. data/lib/alchemy_cms.rb +2 -2
  223. data/lib/generators/alchemy/base.rb +3 -2
  224. data/lib/generators/alchemy/elements/elements_generator.rb +2 -2
  225. data/lib/generators/alchemy/elements/templates/view.html.erb +1 -10
  226. data/lib/generators/alchemy/elements/templates/view.html.haml +1 -9
  227. data/lib/generators/alchemy/elements/templates/view.html.slim +1 -9
  228. data/lib/generators/alchemy/ingredient/ingredient_generator.rb +1 -0
  229. data/lib/generators/alchemy/install/files/alchemy.en.yml +7 -8
  230. data/lib/generators/alchemy/install/files/application.html.erb +1 -1
  231. data/lib/generators/alchemy/install/install_generator.rb +20 -23
  232. data/lib/generators/alchemy/install/templates/elements.yml.tt +12 -12
  233. data/lib/generators/alchemy/module/module_generator.rb +1 -0
  234. data/lib/generators/alchemy/page_layouts/page_layouts_generator.rb +1 -0
  235. data/lib/generators/alchemy/site_layouts/site_layouts_generator.rb +1 -0
  236. data/lib/generators/alchemy/views/views_generator.rb +2 -1
  237. data/lib/tasks/alchemy/thumbnails.rake +6 -25
  238. data/lib/tasks/alchemy/tidy.rake +2 -12
  239. data/lib/tasks/alchemy/upgrade.rake +13 -49
  240. data/package/admin.js +2 -0
  241. data/package/dist/admin.js +16 -0
  242. data/package/dist/admin.js.map +7 -0
  243. data/package/src/datepicker.js +1 -0
  244. data/package/src/tinymce.js +142 -0
  245. data/package.json +5 -3
  246. metadata +41 -135
  247. data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +0 -93
  248. data/app/controllers/alchemy/admin/contents_controller.rb +0 -21
  249. data/app/controllers/alchemy/admin/essence_audios_controller.rb +0 -30
  250. data/app/controllers/alchemy/admin/essence_files_controller.rb +0 -31
  251. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +0 -43
  252. data/app/controllers/alchemy/admin/essence_videos_controller.rb +0 -34
  253. data/app/controllers/alchemy/api/contents_controller.rb +0 -52
  254. data/app/decorators/alchemy/content_editor.rb +0 -119
  255. data/app/helpers/alchemy/admin/contents_helper.rb +0 -42
  256. data/app/helpers/alchemy/admin/essences_helper.rb +0 -31
  257. data/app/models/alchemy/content/factory.rb +0 -143
  258. data/app/models/alchemy/content.rb +0 -247
  259. data/app/models/alchemy/element/element_contents.rb +0 -200
  260. data/app/models/alchemy/element/element_essences.rb +0 -133
  261. data/app/models/alchemy/essence_audio.rb +0 -13
  262. data/app/models/alchemy/essence_boolean.rb +0 -20
  263. data/app/models/alchemy/essence_date.rb +0 -25
  264. data/app/models/alchemy/essence_file.rb +0 -49
  265. data/app/models/alchemy/essence_headline.rb +0 -41
  266. data/app/models/alchemy/essence_html.rb +0 -23
  267. data/app/models/alchemy/essence_link.rb +0 -21
  268. data/app/models/alchemy/essence_node.rb +0 -19
  269. data/app/models/alchemy/essence_page.rb +0 -17
  270. data/app/models/alchemy/essence_picture.rb +0 -67
  271. data/app/models/alchemy/essence_picture_view.rb +0 -90
  272. data/app/models/alchemy/essence_richtext.rb +0 -44
  273. data/app/models/alchemy/essence_select.rb +0 -19
  274. data/app/models/alchemy/essence_text.rb +0 -23
  275. data/app/models/alchemy/essence_video.rb +0 -13
  276. data/app/presenters/alchemy/picture_view.rb +0 -88
  277. data/app/serializers/alchemy/content_serializer.rb +0 -17
  278. data/app/serializers/alchemy/essence_boolean_serializer.rb +0 -10
  279. data/app/serializers/alchemy/essence_date_serializer.rb +0 -10
  280. data/app/serializers/alchemy/essence_file_serializer.rb +0 -13
  281. data/app/serializers/alchemy/essence_html_serializer.rb +0 -10
  282. data/app/serializers/alchemy/essence_link_serializer.rb +0 -13
  283. data/app/serializers/alchemy/essence_picture_serializer.rb +0 -28
  284. data/app/serializers/alchemy/essence_richtext_serializer.rb +0 -11
  285. data/app/serializers/alchemy/essence_select_serializer.rb +0 -10
  286. data/app/serializers/alchemy/essence_text_serializer.rb +0 -22
  287. data/app/views/alchemy/admin/contents/create.js.erb +0 -21
  288. data/app/views/alchemy/admin/essence_audios/edit.html.erb +0 -7
  289. data/app/views/alchemy/admin/essence_files/edit.html.erb +0 -21
  290. data/app/views/alchemy/admin/essence_pictures/destroy.js.erb +0 -5
  291. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +0 -30
  292. data/app/views/alchemy/admin/essence_pictures/save_link.js.erb +0 -3
  293. data/app/views/alchemy/admin/essence_pictures/update.js.erb +0 -8
  294. data/app/views/alchemy/admin/essence_videos/edit.html.erb +0 -12
  295. data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +0 -13
  296. data/app/views/alchemy/essences/_essence_audio_editor.html.erb +0 -4
  297. data/app/views/alchemy/essences/_essence_audio_view.html.erb +0 -15
  298. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +0 -11
  299. data/app/views/alchemy/essences/_essence_boolean_view.html.erb +0 -2
  300. data/app/views/alchemy/essences/_essence_date_editor.html.erb +0 -16
  301. data/app/views/alchemy/essences/_essence_date_view.html.erb +0 -10
  302. data/app/views/alchemy/essences/_essence_file_editor.html.erb +0 -54
  303. data/app/views/alchemy/essences/_essence_file_view.html.erb +0 -18
  304. data/app/views/alchemy/essences/_essence_headline_editor.html.erb +0 -36
  305. data/app/views/alchemy/essences/_essence_headline_view.html.erb +0 -10
  306. data/app/views/alchemy/essences/_essence_html_editor.html.erb +0 -10
  307. data/app/views/alchemy/essences/_essence_html_view.html.erb +0 -2
  308. data/app/views/alchemy/essences/_essence_link_editor.html.erb +0 -30
  309. data/app/views/alchemy/essences/_essence_link_view.html.erb +0 -10
  310. data/app/views/alchemy/essences/_essence_node_editor.html.erb +0 -27
  311. data/app/views/alchemy/essences/_essence_node_view.html.erb +0 -1
  312. data/app/views/alchemy/essences/_essence_page_editor.html.erb +0 -26
  313. data/app/views/alchemy/essences/_essence_page_view.html.erb +0 -5
  314. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +0 -59
  315. data/app/views/alchemy/essences/_essence_picture_view.html.erb +0 -6
  316. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +0 -14
  317. data/app/views/alchemy/essences/_essence_richtext_view.html.erb +0 -4
  318. data/app/views/alchemy/essences/_essence_select_editor.html.erb +0 -28
  319. data/app/views/alchemy/essences/_essence_select_view.html.erb +0 -2
  320. data/app/views/alchemy/essences/_essence_text_editor.html.erb +0 -29
  321. data/app/views/alchemy/essences/_essence_text_view.html.erb +0 -17
  322. data/app/views/alchemy/essences/_essence_video_editor.html.erb +0 -4
  323. data/app/views/alchemy/essences/_essence_video_view.html.erb +0 -19
  324. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +0 -59
  325. data/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb +0 -20
  326. data/app/views/alchemy/pages/show.rss.builder +0 -21
  327. data/db/migrate/20200226213334_alchemy_four_point_four.rb +0 -313
  328. data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +0 -11
  329. data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +0 -28
  330. data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +0 -8
  331. data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +0 -27
  332. data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +0 -6
  333. data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +0 -24
  334. data/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb +0 -22
  335. data/db/migrate/20200907111332_remove_tri_state_booleans.rb +0 -33
  336. data/db/migrate/20201207131309_create_page_versions.rb +0 -19
  337. data/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb +0 -76
  338. data/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb +0 -10
  339. data/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb +0 -7
  340. data/db/migrate/20210406093436_add_alchemy_essence_headlines.rb +0 -12
  341. data/db/migrate/20210506135919_create_essence_audios.rb +0 -19
  342. data/db/migrate/20210506140258_create_essence_videos.rb +0 -23
  343. data/db/migrate/20210508091432_create_alchemy_ingredients.rb +0 -22
  344. data/db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb +0 -13
  345. data/db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb +0 -9
  346. data/lib/alchemy/essence.rb +0 -250
  347. data/lib/alchemy/test_support/essence_shared_examples.rb +0 -271
  348. data/lib/alchemy/test_support/factories/content_factory.rb +0 -20
  349. data/lib/alchemy/test_support/factories/essence_audio_factory.rb +0 -7
  350. data/lib/alchemy/test_support/factories/essence_file_factory.rb +0 -7
  351. data/lib/alchemy/test_support/factories/essence_page_factory.rb +0 -7
  352. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +0 -11
  353. data/lib/alchemy/test_support/factories/essence_text_factory.rb +0 -7
  354. data/lib/alchemy/test_support/factories/essence_video_factory.rb +0 -7
  355. data/lib/alchemy/upgrader/five_point_zero.rb +0 -41
  356. data/lib/alchemy/upgrader/six_point_zero.rb +0 -21
  357. data/lib/alchemy/upgrader/tasks/add_page_versions.rb +0 -33
  358. data/lib/alchemy/upgrader/tasks/element_views_updater.rb +0 -34
  359. data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +0 -29
  360. data/lib/alchemy/upgrader/tasks/ingredients_migrator.rb +0 -74
  361. data/lib/generators/alchemy/essence/essence_generator.rb +0 -49
  362. data/lib/generators/alchemy/essence/templates/editor.html.erb +0 -17
  363. data/lib/generators/alchemy/essence/templates/view.html.erb +0 -2
@@ -37,10 +37,6 @@ module Alchemy
37
37
  def alchemy_guest_user_rules
38
38
  can([:show, :download], Alchemy::Attachment) { |a| !a.restricted? }
39
39
 
40
- can :read, Alchemy::Content, Alchemy::Content.available.not_restricted do |c|
41
- c.public? && !c.restricted?
42
- end
43
-
44
40
  can :read, Alchemy::Element, Alchemy::Element.published.not_restricted do |e|
45
41
  e.public? && !e.restricted?
46
42
  end
@@ -64,10 +60,6 @@ module Alchemy
64
60
  # Resources
65
61
  can [:show, :download], Alchemy::Attachment
66
62
 
67
- can :read, Alchemy::Content, Alchemy::Content.available do |c|
68
- c.public?
69
- end
70
-
71
63
  can :read, Alchemy::Element, Alchemy::Element.published do |e|
72
64
  e.public?
73
65
  end
@@ -97,7 +89,7 @@ module Alchemy
97
89
  :alchemy_admin_pages,
98
90
  :alchemy_admin_pictures,
99
91
  :alchemy_admin_tags,
100
- :alchemy_admin_users,
92
+ :alchemy_admin_users
101
93
  ]
102
94
 
103
95
  # Controller actions
@@ -109,12 +101,7 @@ module Alchemy
109
101
 
110
102
  # Resources
111
103
  can [:read, :download], Alchemy::Attachment
112
- can :manage, Alchemy::Content
113
104
  can :manage, Alchemy::Element
114
- can :manage, Alchemy::EssenceAudio
115
- can :manage, Alchemy::EssenceFile
116
- can :manage, Alchemy::EssencePicture
117
- can :manage, Alchemy::EssenceVideo
118
105
  can :manage, Alchemy::Ingredient
119
106
  can [:crop], Alchemy::Ingredients::Picture
120
107
  can :manage, Alchemy::LegacyPageUrl
@@ -140,7 +127,7 @@ module Alchemy
140
127
  # Navigation
141
128
  can :index, [
142
129
  :alchemy_admin_languages,
143
- :alchemy_admin_users,
130
+ :alchemy_admin_users
144
131
  ]
145
132
 
146
133
  # Resources
@@ -149,7 +136,7 @@ module Alchemy
149
136
  :copy_language_tree,
150
137
  :flush,
151
138
  :order,
152
- :switch_language,
139
+ :switch_language
153
140
  ], Alchemy::Page
154
141
 
155
142
  # Resources which may be locked via template permissions
@@ -162,7 +149,7 @@ module Alchemy
162
149
  #
163
150
  can([
164
151
  :create,
165
- :destroy,
152
+ :destroy
166
153
  ], Alchemy::Page) { |p| p.editable_by?(@user) }
167
154
 
168
155
  can(:publish, Alchemy::Page) do |page|
@@ -173,6 +160,7 @@ module Alchemy
173
160
  can :manage, Alchemy::Attachment
174
161
  can :manage, Alchemy::Tag
175
162
  can :index, Alchemy::Language
163
+ can :switch, Alchemy::Language
176
164
  end
177
165
  end
178
166
 
@@ -101,8 +101,8 @@ module Alchemy
101
101
  attr_accessor :resource_relations, :model_associations
102
102
  attr_reader :model
103
103
 
104
- DEFAULT_SKIPPED_ATTRIBUTES = %w(id created_at creator_id)
105
- DEFAULT_SKIPPED_ASSOCIATIONS = %w(creator)
104
+ DEFAULT_SKIPPED_ATTRIBUTES = %w[id created_at creator_id]
105
+ DEFAULT_SKIPPED_ASSOCIATIONS = %w[creator]
106
106
  SEARCHABLE_COLUMN_TYPES = [:string, :text]
107
107
 
108
108
  def initialize(controller_path, module_definition = nil, custom_model = nil)
@@ -169,7 +169,7 @@ module Alchemy
169
169
  name: col.name,
170
170
  type: resource_column_type(col),
171
171
  relation: resource_relation(col.name),
172
- enum: enum_values_collection_for_select(col.name),
172
+ enum: enum_values_collection_for_select(col.name)
173
173
  }.delete_if { |_k, v| v.blank? }
174
174
  end.compact
175
175
  end
@@ -183,16 +183,16 @@ module Alchemy
183
183
  ::I18n.t(key, scope: [
184
184
  :activerecord, :attributes, model.model_name.i18n_key, "#{column_name}_values"
185
185
  ], default: key.humanize),
186
- key,
186
+ key
187
187
  ]
188
188
  end
189
189
  end
190
190
 
191
191
  def sorted_attributes
192
- @_sorted_attributes ||= attributes.
193
- sort_by { |attr| attr[:name] == "name" ? 0 : 1 }.
194
- sort_by! { |attr| attr[:type] == :boolean ? 1 : 0 }.
195
- sort_by! { |attr| attr[:name] == "updated_at" ? 1 : 0 }
192
+ @_sorted_attributes ||= attributes
193
+ .sort_by { |attr| (attr[:name] == "name") ? 0 : 1 }
194
+ .sort_by! { |attr| (attr[:type] == :boolean) ? 1 : 0 }
195
+ .sort_by! { |attr| (attr[:name] == "updated_at") ? 1 : 0 }
196
196
  end
197
197
 
198
198
  def editable_attributes
@@ -281,7 +281,7 @@ module Alchemy
281
281
  def searchable_relation_attribute(attribute)
282
282
  {
283
283
  name: "#{attribute[:relation][:model_association].name}_#{attribute[:relation][:attr_method]}",
284
- type: attribute[:relation][:attr_type],
284
+ type: attribute[:relation][:attr_type]
285
285
  }
286
286
  end
287
287
 
@@ -325,7 +325,7 @@ module Alchemy
325
325
  resource_relations[foreign_key] = options.merge(
326
326
  model_association: association,
327
327
  name: relation_name,
328
- collection: collection,
328
+ collection: collection
329
329
  )
330
330
  end
331
331
  end
@@ -23,7 +23,7 @@ module Alchemy
23
23
 
24
24
  def resource_url_proxy
25
25
  if resource_handler.in_engine?
26
- eval(resource_handler.engine_name)
26
+ eval(resource_handler.engine_name) # rubocop:disable Security/Eval
27
27
  else
28
28
  main_app
29
29
  end
@@ -80,11 +80,11 @@ module Alchemy
80
80
  value = record.present? ? record.send(attribute[:relation][:attr_method]) : Alchemy.t(:not_found)
81
81
  elsif attribute_value && attribute[:type].to_s =~ /(date|time)/
82
82
  localization_format = if attribute[:type] == :datetime
83
- options[:datetime_format] || :'alchemy.default'
83
+ options[:datetime_format] || :"alchemy.default"
84
84
  elsif attribute[:type] == :date
85
- options[:date_format] || :'alchemy.default'
85
+ options[:date_format] || :"alchemy.default"
86
86
  else
87
- options[:time_format] || :'alchemy.time'
87
+ options[:time_format] || :"alchemy.time"
88
88
  end
89
89
  value = l(attribute_value, format: localization_format)
90
90
  else
@@ -110,8 +110,8 @@ module Alchemy
110
110
  options.merge(
111
111
  as: "string",
112
112
  input_html: {
113
- data: { datepicker_type: input_type },
114
- },
113
+ data: {datepicker_type: input_type}
114
+ }
115
115
  )
116
116
  when "text"
117
117
  options.merge(as: "text", input_html: {rows: 4})
@@ -135,7 +135,7 @@ module Alchemy
135
135
  # If the attribute contains a resource_relation, then the table and column for related model will be returned.
136
136
  #
137
137
  def sortable_resource_header_column(attribute)
138
- if relation = attribute[:relation]
138
+ if (relation = attribute[:relation])
139
139
  "#{relation[:model_association].name}_#{relation[:attr_method]}"
140
140
  else
141
141
  attribute[:name]
@@ -6,7 +6,7 @@ module Alchemy
6
6
  # Alchemy has a very strong catch all route.
7
7
  # But we don't want to handle all requests.
8
8
  #
9
- # For instance we only want to handle html and rss requests and
9
+ # For instance we only want to handle html requests and
10
10
  # don't want to swallow the rails/info routes in development mode.
11
11
  #
12
12
  class RoutingConstraints
@@ -21,20 +21,20 @@ module Alchemy
21
21
 
22
22
  private
23
23
 
24
- # We only want html and rss requests to be handled by us.
24
+ # We only want html requests to be handled by us.
25
25
  #
26
26
  # If an unknown format is requested we want to handle this,
27
27
  # because it could be a legacy route that needs to be redirected.
28
28
  #
29
29
  def handable_format?
30
- @request.format.symbol.nil? || (@request.format.symbol == :html) || (@request.format.symbol == :rss)
30
+ @request.format.symbol.nil? || (@request.format.symbol == :html)
31
31
  end
32
32
 
33
33
  # We don't want to handle the Rails info routes.
34
34
  def no_rails_route?
35
- return true if !%w(development test).include?(Rails.env)
35
+ return true if !%w[development test].include?(Rails.env)
36
36
 
37
- (@params["urlname"] =~ /\Arails\//).nil?
37
+ !@params["urlname"].start_with?("rails/")
38
38
  end
39
39
  end
40
40
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ # Defines the methods that are needed to
5
+ # make a model searchable in Alchemy's admin search by Ransack.
6
+ module SearchableResource
7
+ SEARCHABLE_COLUMN_TYPES = %i[string text]
8
+
9
+ # Allow all string and text attributes to be searchable by Ransack.
10
+ def ransackable_attributes(_auth_object = nil)
11
+ searchable_alchemy_resource_attributes
12
+ end
13
+
14
+ # Allow all attributes to be sortable by Ransack.
15
+ def ransortable_attributes(_auth_object = nil)
16
+ columns.map(&:name)
17
+ end
18
+
19
+ # Allow all associations defined in +alchemy_resource_relations+ to be searchable by Ransack.
20
+ def ransackable_associations(_auth_object = nil)
21
+ searchable_alchemy_resource_associations
22
+ end
23
+
24
+ protected
25
+
26
+ def searchable_alchemy_resource_attributes
27
+ columns.select { |c| c.type.in?(SEARCHABLE_COLUMN_TYPES) }.map(&:name)
28
+ end
29
+
30
+ def searchable_alchemy_resource_associations
31
+ if respond_to?(:alchemy_resource_relations)
32
+ alchemy_resource_relations.keys.map!(&:to_s)
33
+ else
34
+ []
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "alchemy/shell"
3
4
 
4
5
  module Alchemy
@@ -46,7 +47,7 @@ module Alchemy
46
47
  contentpages.each do |page|
47
48
  create_page(page, {
48
49
  language: Alchemy::Language.default,
49
- language_root: true,
50
+ language_root: true
50
51
  })
51
52
  end
52
53
  end
@@ -55,7 +56,7 @@ module Alchemy
55
56
  desc "Seeding Alchemy layout pages from #{page_seeds_file}"
56
57
  language = Alchemy::Language.default
57
58
  layoutpages.each do |page|
58
- create_page(page, { language: language })
59
+ create_page(page, {language: language})
59
60
  end
60
61
  end
61
62
 
@@ -125,7 +126,7 @@ module Alchemy
125
126
  page_layout: default_language["page_layout"],
126
127
  public: true,
127
128
  default: true,
128
- site: Alchemy::Site.default,
129
+ site: Alchemy::Site.default
129
130
  )
130
131
  else
131
132
  raise DefaultLanguageNotFoundError
data/lib/alchemy/shell.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "thor/shell/color"
3
4
 
4
5
  module Alchemy
@@ -10,7 +11,7 @@ module Alchemy
10
11
  clear: Thor::Shell::Color::CLEAR,
11
12
  green: Thor::Shell::Color::GREEN,
12
13
  red: Thor::Shell::Color::RED,
13
- yellow: Thor::Shell::Color::YELLOW,
14
+ yellow: Thor::Shell::Color::YELLOW
14
15
  }.freeze
15
16
 
16
17
  def self.silence!
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Alchemy
3
4
  # ActsAsTaggableOn to Gutentag interface compatibility module
4
5
  # Include this module to add tagging support to your model.
@@ -28,11 +29,11 @@ module Alchemy
28
29
  end
29
30
 
30
31
  unless args[:match]
31
- args.merge!(match: :all)
32
+ args[:match] = :all
32
33
  end
33
34
 
34
35
  if names.any?
35
- args.merge!(names: names)
36
+ args[:names] = names
36
37
  end
37
38
 
38
39
  super(args)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "alchemy/shell"
3
4
 
4
5
  module Alchemy
@@ -25,25 +26,6 @@ module Alchemy
25
26
  end
26
27
  end
27
28
 
28
- def update_content_positions
29
- Alchemy::Element.all.each do |element|
30
- if element.contents.any?
31
- puts "\n## Updating content positions of element `#{element.name}`"
32
- end
33
- element.contents.group_by(&:element_id).each do |_, contents|
34
- contents.each_with_index do |content, idx|
35
- position = idx + 1
36
- if content.position != position
37
- log "Updating position for content ##{content.id} to #{position}"
38
- content.update_column(:position, position)
39
- else
40
- log "Position for content ##{content.id} is already correct (#{position})", :skip
41
- end
42
- end
43
- end
44
- end
45
- end
46
-
47
29
  def remove_orphaned_elements
48
30
  puts "\n## Removing orphaned elements"
49
31
  elements = Alchemy::Element.unscoped.not_nested
@@ -79,25 +61,6 @@ module Alchemy
79
61
  end
80
62
  end
81
63
 
82
- def remove_orphaned_contents
83
- puts "\n## Removing orphaned contents"
84
- contents = Alchemy::Content.unscoped.all
85
- if contents.any?
86
- orphaned_contents = contents.select do |content|
87
- content.essence.nil? && content.essence_id.present? ||
88
- content.element.nil? && content.element_id.present?
89
- end
90
- if orphaned_contents.any?
91
- log "Found #{orphaned_contents.size} orphaned contents"
92
- destroy_orphaned_records(orphaned_contents, "content")
93
- else
94
- log "No orphaned contents found", :skip
95
- end
96
- else
97
- log "No contents found", :skip
98
- end
99
- end
100
-
101
64
  def remove_duplicate_legacy_urls
102
65
  puts "\n## Removing duplicate legacy URLs"
103
66
  sql = <<~SQL
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module TestSupport
5
+ module CapybaraHelpers
6
+ # Select2 capybara helper
7
+ def select2(value, options)
8
+ label = find_label_by_text(options[:from])
9
+
10
+ select2_anchor_selector = ".select2-container a"
11
+
12
+ if label.has_css?(select2_anchor_selector)
13
+ label.find(select2_anchor_selector).click
14
+ else
15
+ within label.find(:xpath, "..") do
16
+ find(select2_anchor_selector).click
17
+ end
18
+ end
19
+
20
+ within_entire_page do
21
+ page.find(
22
+ "div.select2-result-label",
23
+ text: /#{Regexp.escape(value)}/i, match: :prefer_exact
24
+ ).click
25
+ end
26
+ end
27
+
28
+ def select2_search(value, options)
29
+ if options[:from]
30
+ label = find_label_by_text(options[:from])
31
+ within label.first(:xpath, ".//..") do
32
+ options[:from] = "##{find(".select2-container")["id"]}"
33
+ end
34
+ elsif options[:element_id] && options[:ingredient_role]
35
+ container_id = find("#element_#{options[:element_id]} [data-ingredient-role='#{options[:ingredient_role]}'] .select2-container")["id"]
36
+ options[:from] = "##{container_id}"
37
+ end
38
+
39
+ find("#{options[:from]}:not(.select2-container-disabled):not(.select2-offscreen)").click
40
+
41
+ within_entire_page do
42
+ find("input.select2-input.select2-focused").set(value)
43
+ expect(page).to have_selector(".select2-result-label", visible: true)
44
+ find("div.select2-result-label", text: /#{Regexp.escape(value)}/i, match: :prefer_exact).click
45
+ expect(page).not_to have_selector(".select2-result-label")
46
+ end
47
+ end
48
+
49
+ def click_button_with_label(label)
50
+ label = find("label", text: label)
51
+ within label.first(:xpath, ".//..") do
52
+ first("button").click
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def within_entire_page(&block)
59
+ within(:xpath, "//body", &block)
60
+ end
61
+
62
+ def find_label_by_text(text)
63
+ find "label:not(.select2-offscreen)",
64
+ text: /#{Regexp.escape(text)}/i,
65
+ match: :one
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Alchemy
3
4
  module TestSupport
4
5
  # Allows you to stub the Alchemy configuration in your specs
@@ -3,7 +3,6 @@
3
3
  FactoryBot.define do
4
4
  factory :alchemy_element, class: "Alchemy::Element" do
5
5
  name { "article" }
6
- autogenerate_contents { false }
7
6
  autogenerate_ingredients { false }
8
7
  association :page_version, factory: :alchemy_page_version
9
8
 
@@ -26,12 +25,11 @@ FactoryBot.define do
26
25
  name { "slide" }
27
26
  end
28
27
 
29
- trait :with_contents do
30
- autogenerate_contents { true }
28
+ trait :compact do
29
+ name { "slide" }
31
30
  end
32
31
 
33
32
  trait :with_ingredients do
34
- name { "element_with_ingredients" }
35
33
  autogenerate_ingredients { true }
36
34
  end
37
35
  end
@@ -19,7 +19,7 @@ FactoryBot.define do
19
19
  factory :"alchemy_ingredient_#{ingredient}", class: "Alchemy::Ingredients::#{ingredient.classify}" do
20
20
  role { ingredient }
21
21
  type { "Alchemy::Ingredients::#{ingredient.classify}" }
22
- association :element, name: "all_you_can_eat_ingredients", factory: :alchemy_element
22
+ association :element, name: "all_you_can_eat", factory: :alchemy_element
23
23
  end
24
24
  end
25
25
  end
@@ -36,16 +36,18 @@ FactoryBot.define do
36
36
  after(:build) do |page, evaluator|
37
37
  page.build_public_version(
38
38
  public_on: evaluator.public_on,
39
- public_until: evaluator.public_until,
39
+ public_until: evaluator.public_until
40
40
  )
41
41
  end
42
42
  after(:create) do |page|
43
43
  if page.autogenerate_elements
44
44
  page.definition["autogenerate"].each do |name|
45
- create(:alchemy_element,
45
+ create(
46
+ :alchemy_element,
46
47
  name: name,
47
48
  page_version: page.public_version,
48
- autogenerate_contents: true)
49
+ autogenerate_ingredients: true
50
+ )
49
51
  end
50
52
  end
51
53
  end
@@ -10,20 +10,20 @@ RSpec.shared_examples_for "having crop action" do |args|
10
10
 
11
11
  context "with no picture assigned" do
12
12
  it "renders error message" do
13
- get :crop, params: { id: 1 }
13
+ get :crop, params: {id: 1}
14
14
  expect(assigns(:no_image_notice)).to eq(Alchemy.t(:no_image_for_cropper_found))
15
15
  end
16
16
  end
17
17
 
18
18
  context "with picture assigned" do
19
- subject { get :crop, params: { id: 1, picture_id: picture.id } }
19
+ subject { get :crop, params: {id: 1, picture_id: picture.id} }
20
20
 
21
21
  let(:default_mask) do
22
22
  [
23
23
  0,
24
24
  0,
25
25
  300,
26
- 250,
26
+ 250
27
27
  ]
28
28
  end
29
29
 
@@ -43,7 +43,7 @@ RSpec.shared_examples_for "having crop action" do |args|
43
43
 
44
44
  context "with sizes in settings" do
45
45
  let(:settings) do
46
- { size: "300x250" }
46
+ {size: "300x250"}
47
47
  end
48
48
 
49
49
  it "sets sizes to given values" do
@@ -78,7 +78,7 @@ RSpec.shared_examples_for "having crop action" do |args|
78
78
 
79
79
  context "and aspect ratio set on the settings" do
80
80
  let(:settings) do
81
- { fixed_ratio: "2" }
81
+ {fixed_ratio: "2"}
82
82
  end
83
83
 
84
84
  it "does not infer the height from the image file preserving the aspect ratio" do
@@ -93,7 +93,7 @@ RSpec.shared_examples_for "having crop action" do |args|
93
93
  context "when width or height is not fixed and an aspect ratio is given" do
94
94
  context "and aspect ratio set on the settings" do
95
95
  let(:settings) do
96
- { fixed_ratio: "0.5" }
96
+ {fixed_ratio: "0.5"}
97
97
  end
98
98
 
99
99
  it "width is given, it infers the height from width and ratio" do
@@ -136,7 +136,7 @@ RSpec.shared_examples_for "having crop action" do |args|
136
136
 
137
137
  context "with fixed_ratio set to false" do
138
138
  let(:settings) do
139
- { fixed_ratio: false }
139
+ {fixed_ratio: false}
140
140
  end
141
141
 
142
142
  it "sets ratio to false" do
@@ -147,7 +147,7 @@ RSpec.shared_examples_for "having crop action" do |args|
147
147
 
148
148
  context "with fixed_ratio set to a non float string" do
149
149
  let(:settings) do
150
- { fixed_ratio: "123,45" }
150
+ {fixed_ratio: "123,45"}
151
151
  end
152
152
 
153
153
  it "raises error" do
@@ -157,7 +157,7 @@ RSpec.shared_examples_for "having crop action" do |args|
157
157
 
158
158
  context "with no fixed_ratio set" do
159
159
  let(:settings) do
160
- { size: "80x60" }
160
+ {size: "80x60"}
161
161
  end
162
162
 
163
163
  it "sets a fixed ratio from sizes" do