From c7dd08567fddf7903b69ca026ac43dead6c734ac Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Thu, 19 Jan 2023 09:55:00 +0100 Subject: [PATCH] Remove all content/essence related code This is a HUGE commit, but it is atomic and this is good. --- .../alchemy/alchemy.dirty.js.coffee | 2 +- .../alchemy/alchemy.element_editors.js.coffee | 50 +- app/assets/stylesheets/alchemy/elements.scss | 28 +- .../alchemy/admin/contents_controller.rb | 21 - .../alchemy/admin/elements_controller.rb | 39 +- .../admin/essence_audios_controller.rb | 30 - .../alchemy/admin/essence_files_controller.rb | 31 - .../admin/essence_pictures_controller.rb | 43 -- .../admin/essence_videos_controller.rb | 34 -- .../alchemy/admin/pictures_controller.rb | 2 +- .../alchemy/api/contents_controller.rb | 52 -- .../alchemy/api/elements_controller.rb | 2 - app/decorators/alchemy/content_editor.rb | 119 ---- app/decorators/alchemy/element_editor.rb | 15 +- app/helpers/alchemy/admin/contents_helper.rb | 42 -- app/helpers/alchemy/admin/elements_helper.rb | 2 - app/helpers/alchemy/admin/essences_helper.rb | 31 - app/helpers/alchemy/elements_block_helper.rb | 45 +- app/models/alchemy/attachment.rb | 9 +- app/models/alchemy/content.rb | 247 -------- app/models/alchemy/content/factory.rb | 143 ----- app/models/alchemy/eager_loading.rb | 1 - app/models/alchemy/element.rb | 13 +- .../alchemy/element/element_contents.rb | 126 ----- .../alchemy/element/element_essences.rb | 125 ---- app/models/alchemy/element/presenters.rb | 20 +- app/models/alchemy/essence_audio.rb | 13 - app/models/alchemy/essence_boolean.rb | 20 - app/models/alchemy/essence_date.rb | 25 - app/models/alchemy/essence_file.rb | 49 -- app/models/alchemy/essence_headline.rb | 41 -- app/models/alchemy/essence_html.rb | 23 - app/models/alchemy/essence_link.rb | 21 - app/models/alchemy/essence_node.rb | 19 - app/models/alchemy/essence_page.rb | 17 - app/models/alchemy/essence_picture.rb | 67 --- app/models/alchemy/essence_picture_view.rb | 90 --- app/models/alchemy/essence_richtext.rb | 44 -- app/models/alchemy/essence_select.rb | 19 - app/models/alchemy/essence_text.rb | 23 - app/models/alchemy/essence_video.rb | 13 - app/models/alchemy/ingredient.rb | 2 + app/models/alchemy/node.rb | 15 +- app/models/alchemy/page/page_elements.rb | 19 +- app/models/alchemy/picture.rb | 13 +- app/serializers/alchemy/content_serializer.rb | 17 - app/serializers/alchemy/element_serializer.rb | 7 +- .../alchemy/essence_boolean_serializer.rb | 10 - .../alchemy/essence_date_serializer.rb | 10 - .../alchemy/essence_file_serializer.rb | 13 - .../alchemy/essence_html_serializer.rb | 10 - .../alchemy/essence_link_serializer.rb | 13 - .../alchemy/essence_picture_serializer.rb | 28 - .../alchemy/essence_richtext_serializer.rb | 11 - .../alchemy/essence_select_serializer.rb | 10 - .../alchemy/essence_text_serializer.rb | 22 - app/services/alchemy/delete_elements.rb | 8 +- app/services/alchemy/duplicate_element.rb | 7 +- .../alchemy/admin/contents/create.js.erb | 21 - .../alchemy/admin/elements/_element.html.erb | 27 +- .../alchemy/admin/elements/create.js.erb | 2 +- app/views/alchemy/admin/elements/fold.js.erb | 4 +- .../alchemy/admin/elements/update.js.erb | 3 +- .../admin/essence_audios/edit.html.erb | 7 - .../alchemy/admin/essence_files/edit.html.erb | 21 - .../admin/essence_pictures/destroy.js.erb | 5 - .../admin/essence_pictures/edit.html.erb | 30 - .../admin/essence_pictures/save_link.js.erb | 3 - .../admin/essence_pictures/update.js.erb | 8 - .../admin/essence_videos/edit.html.erb | 12 - app/views/alchemy/admin/pages/edit.html.erb | 2 +- .../essences/_essence_audio_editor.html.erb | 4 - .../essences/_essence_audio_view.html.erb | 15 - .../essences/_essence_boolean_editor.html.erb | 11 - .../essences/_essence_boolean_view.html.erb | 2 - .../essences/_essence_date_editor.html.erb | 16 - .../essences/_essence_date_view.html.erb | 10 - .../essences/_essence_file_editor.html.erb | 54 -- .../essences/_essence_file_view.html.erb | 18 - .../_essence_headline_editor.html.erb | 36 -- .../essences/_essence_headline_view.html.erb | 10 - .../essences/_essence_html_editor.html.erb | 10 - .../essences/_essence_html_view.html.erb | 2 - .../essences/_essence_link_editor.html.erb | 30 - .../essences/_essence_link_view.html.erb | 10 - .../essences/_essence_node_editor.html.erb | 27 - .../essences/_essence_node_view.html.erb | 1 - .../essences/_essence_page_editor.html.erb | 26 - .../essences/_essence_page_view.html.erb | 5 - .../essences/_essence_picture_editor.html.erb | 59 -- .../essences/_essence_picture_view.html.erb | 6 - .../_essence_richtext_editor.html.erb | 14 - .../essences/_essence_richtext_view.html.erb | 4 - .../essences/_essence_select_editor.html.erb | 28 - .../essences/_essence_select_view.html.erb | 2 - .../essences/_essence_text_editor.html.erb | 29 - .../essences/_essence_text_view.html.erb | 17 - .../essences/_essence_video_editor.html.erb | 4 - .../essences/_essence_video_view.html.erb | 19 - .../shared/_essence_picture_tools.html.erb | 59 -- .../shared/_linkable_essence_tools.html.erb | 20 - .../ingredients/_boolean_editor.html.erb | 2 +- .../ingredients/_headline_editor.html.erb | 2 +- .../alchemy/ingredients/_html_editor.html.erb | 2 +- .../alchemy/ingredients/_node_editor.html.erb | 2 +- .../ingredients/_select_editor.html.erb | 2 +- .../alchemy/ingredients/_text_editor.html.erb | 2 +- config/locales/alchemy.en.yml | 141 +++-- config/routes.rb | 17 +- .../20200226213334_alchemy_four_point_four.rb | 113 ---- ...0423073425_create_alchemy_essence_nodes.rb | 11 - ...0200907111332_remove_tri_state_booleans.rb | 5 - ...tized_body_to_alchemy_essence_richtexts.rb | 7 - ...406093436_add_alchemy_essence_headlines.rb | 12 - .../20210506135919_create_essence_audios.rb | 19 - .../20210506140258_create_essence_videos.rb | 23 - ...d_playsinline_to_alchemy_essence_videos.rb | 9 - lib/alchemy/deprecation.rb | 2 +- lib/alchemy/essence.rb | 250 -------- lib/alchemy/permissions.rb | 13 - .../test_support/essence_shared_examples.rb | 271 --------- .../test_support/factories/content_factory.rb | 20 - .../test_support/factories/element_factory.rb | 6 - .../factories/essence_audio_factory.rb | 7 - .../factories/essence_file_factory.rb | 7 - .../factories/essence_page_factory.rb | 7 - .../factories/essence_picture_factory.rb | 11 - .../factories/essence_text_factory.rb | 7 - .../factories/essence_video_factory.rb | 7 - .../test_support/factories/page_factory.rb | 6 +- lib/alchemy/upgrader/six_point_zero.rb | 7 - .../upgrader/tasks/ingredients_migrator.rb | 74 --- lib/alchemy_cms.rb | 1 - .../alchemy/essence/essence_generator.rb | 49 -- .../alchemy/essence/templates/editor.html.erb | 17 - .../alchemy/essence/templates/view.html.erb | 2 - .../alchemy/admin/elements_controller_spec.rb | 35 -- .../admin/essence_audios_controller_spec.rb | 54 -- .../admin/essence_files_controller_spec.rb | 59 -- .../admin/essence_pictures_controller_spec.rb | 66 --- .../admin/essence_videos_controller_spec.rb | 60 -- .../alchemy/admin/pictures_controller_spec.rb | 7 +- .../alchemy/api/contents_controller_spec.rb | 143 ----- .../alchemy/pages_controller_spec.rb | 6 +- .../decorators/alchemy/content_editor_spec.rb | 199 ------- .../decorators/alchemy/element_editor_spec.rb | 72 +-- spec/dummy/app/models/dummy_model.rb | 5 - spec/dummy/config/alchemy/elements.yml | 189 +++---- .../20150412103152_create_dummy_model.rb | 9 - .../20200226213334_alchemy_four_point_four.rb | 1 - ...0423073425_create_alchemy_essence_nodes.rb | 1 - ...0200504210159_remove_site_id_from_nodes.rb | 1 - ...anguage_id_foreign_key_to_alchemy_pages.rb | 1 - ...11113603_add_menu_type_to_alchemy_nodes.rb | 1 - ...4091507_make_page_layoutpage_null_false.rb | 1 - ...73500_remove_visible_from_alchemy_pages.rb | 1 - ...617110713_create_alchemy_picture_thumbs.rb | 1 - ...0200907111332_remove_tri_state_booleans.rb | 1 - .../20201207131309_create_page_versions.rb | 1 - ...add_page_version_id_to_alchemy_elements.rb | 1 - ...ic_on_and_public_until_on_alchemy_pages.rb | 1 - ...tized_body_to_alchemy_essence_richtexts.rb | 1 - ...406093436_add_alchemy_essence_headlines.rb | 1 - .../20210506135919_create_essence_audios.rb | 1 - .../20210506140258_create_essence_videos.rb | 1 - ...210508091432_create_alchemy_ingredients.rb | 1 - ...nline_to_alchemy_essence_videos.alchemy.rb | 10 - ...0230119091654_gutentag_tables.gutentag.rb} | 9 +- ...091655_gutentag_cache_counter.gutentag.rb} | 9 +- ...230119091656_no_null_counters.gutentag.rb} | 6 +- ...9091717_alchemy_four_point_four.alchemy.rb | 201 +++++++ ...91718_remove_site_id_from_nodes.alchemy.rb | 29 + ...id_foreign_key_to_alchemy_pages.alchemy.rb | 9 + ..._add_menu_type_to_alchemy_nodes.alchemy.rb | 28 + ...make_page_layoutpage_null_false.alchemy.rb | 7 + ...move_visible_from_alchemy_pages.alchemy.rb | 25 + ...3_create_alchemy_picture_thumbs.alchemy.rb | 23 + ...91724_remove_tri_state_booleans.alchemy.rb | 29 + ...0119091725_create_page_versions.alchemy.rb | 20 + ..._version_id_to_alchemy_elements.alchemy.rb | 77 +++ ...d_public_until_on_alchemy_pages.alchemy.rb | 11 + ...1728_create_alchemy_ingredients.alchemy.rb | 23 + ...foreign_key_from_alchemy_nodes.alchemy.rb} | 3 + spec/dummy/db/schema.rb | 126 +---- .../admin/edit_elements_feature_spec.rb | 76 ++- spec/features/admin/link_overlay_spec.rb | 6 +- .../admin/node_select_feature_spec.rb | 4 +- .../admin/page_editing_feature_spec.rb | 40 +- .../admin/picture_assignment_overlay_spec.rb | 8 +- .../admin/resources_integration_spec.rb | 10 +- spec/features/page_feature_spec.rb | 4 +- .../helpers/alchemy/admin/base_helper_spec.rb | 12 +- .../alchemy/admin/contents_helper_spec.rb | 90 --- .../alchemy/admin/essences_helper_spec.rb | 91 --- .../alchemy/elements_block_helper_spec.rb | 66 --- spec/helpers/alchemy/elements_helper_spec.rb | 2 +- .../tasks/ingredients_migrator_spec.rb | 32 -- spec/libraries/permissions_spec.rb | 26 +- spec/models/alchemy/attachment_spec.rb | 9 +- spec/models/alchemy/content_spec.rb | 533 ------------------ spec/models/alchemy/eager_loading_spec.rb | 2 - .../alchemy/element_ingredients_spec.rb | 48 +- spec/models/alchemy/element_spec.rb | 358 +----------- spec/models/alchemy/essence_audio_spec.rb | 12 - spec/models/alchemy/essence_boolean_spec.rb | 12 - spec/models/alchemy/essence_date_spec.rb | 32 -- spec/models/alchemy/essence_file_spec.rb | 42 -- spec/models/alchemy/essence_headline_spec.rb | 90 --- spec/models/alchemy/essence_html_spec.rb | 20 - spec/models/alchemy/essence_link_spec.rb | 12 - spec/models/alchemy/essence_node_spec.rb | 23 - spec/models/alchemy/essence_page_spec.rb | 21 - spec/models/alchemy/essence_picture_spec.rb | 103 ---- .../alchemy/essence_picture_view_spec.rb | 332 ----------- spec/models/alchemy/essence_richtext_spec.rb | 62 -- spec/models/alchemy/essence_select_spec.rb | 12 - spec/models/alchemy/essence_text_spec.rb | 112 ---- spec/models/alchemy/essence_video_spec.rb | 12 - spec/models/alchemy/node_spec.rb | 9 +- spec/models/alchemy/page_spec.rb | 139 ++--- spec/models/alchemy/page_version_spec.rb | 9 +- spec/models/alchemy/picture_spec.rb | 17 +- spec/models/dummy_model_spec.rb | 12 - spec/rails_helper.rb | 11 +- .../alchemy/admin/contents_controller_spec.rb | 23 - spec/routing/api_routing_spec.rb | 68 +-- .../alchemy/element_serializer_spec.rb | 1 - spec/services/alchemy/delete_elements_spec.rb | 24 +- .../alchemy/duplicate_element_spec.rb | 12 +- spec/support/capybara_helpers.rb | 11 +- .../admin/essence_pictures/edit_spec.rb | 54 -- .../essences/essence_audio_editor_spec.rb | 71 --- .../views/essences/essence_audio_view_spec.rb | 34 -- .../essences/essence_boolean_editor_spec.rb | 47 -- .../essences/essence_boolean_view_spec.rb | 25 - .../essences/essence_date_editor_spec.rb | 18 - spec/views/essences/essence_date_view_spec.rb | 40 -- .../essences/essence_file_editor_spec.rb | 71 --- spec/views/essences/essence_file_view_spec.rb | 88 --- spec/views/essences/essence_html_view_spec.rb | 24 - .../essences/essence_link_editor_spec.rb | 28 - spec/views/essences/essence_link_view_spec.rb | 43 -- .../essences/essence_page_editor_spec.rb | 31 - spec/views/essences/essence_page_view_spec.rb | 30 - .../essences/essence_picture_editor_spec.rb | 85 --- .../essences/essence_picture_view_spec.rb | 14 - .../essences/essence_richtext_view_spec.rb | 34 -- .../essences/essence_select_editor_spec.rb | 38 -- .../essences/essence_select_view_spec.rb | 13 - .../essences/essence_text_editor_spec.rb | 51 -- spec/views/essences/essence_text_view_spec.rb | 53 -- .../essences/essence_video_editor_spec.rb | 71 --- .../views/essences/essence_video_view_spec.rb | 34 -- 253 files changed, 1008 insertions(+), 8002 deletions(-) delete mode 100644 app/controllers/alchemy/admin/contents_controller.rb delete mode 100644 app/controllers/alchemy/admin/essence_audios_controller.rb delete mode 100644 app/controllers/alchemy/admin/essence_files_controller.rb delete mode 100644 app/controllers/alchemy/admin/essence_pictures_controller.rb delete mode 100644 app/controllers/alchemy/admin/essence_videos_controller.rb delete mode 100644 app/controllers/alchemy/api/contents_controller.rb delete mode 100644 app/decorators/alchemy/content_editor.rb delete mode 100644 app/helpers/alchemy/admin/contents_helper.rb delete mode 100644 app/helpers/alchemy/admin/essences_helper.rb delete mode 100644 app/models/alchemy/content.rb delete mode 100644 app/models/alchemy/content/factory.rb delete mode 100644 app/models/alchemy/element/element_contents.rb delete mode 100644 app/models/alchemy/element/element_essences.rb delete mode 100644 app/models/alchemy/essence_audio.rb delete mode 100644 app/models/alchemy/essence_boolean.rb delete mode 100644 app/models/alchemy/essence_date.rb delete mode 100644 app/models/alchemy/essence_file.rb delete mode 100644 app/models/alchemy/essence_headline.rb delete mode 100644 app/models/alchemy/essence_html.rb delete mode 100644 app/models/alchemy/essence_link.rb delete mode 100644 app/models/alchemy/essence_node.rb delete mode 100644 app/models/alchemy/essence_page.rb delete mode 100644 app/models/alchemy/essence_picture.rb delete mode 100644 app/models/alchemy/essence_picture_view.rb delete mode 100644 app/models/alchemy/essence_richtext.rb delete mode 100644 app/models/alchemy/essence_select.rb delete mode 100644 app/models/alchemy/essence_text.rb delete mode 100644 app/models/alchemy/essence_video.rb delete mode 100644 app/serializers/alchemy/content_serializer.rb delete mode 100644 app/serializers/alchemy/essence_boolean_serializer.rb delete mode 100644 app/serializers/alchemy/essence_date_serializer.rb delete mode 100644 app/serializers/alchemy/essence_file_serializer.rb delete mode 100644 app/serializers/alchemy/essence_html_serializer.rb delete mode 100644 app/serializers/alchemy/essence_link_serializer.rb delete mode 100644 app/serializers/alchemy/essence_picture_serializer.rb delete mode 100644 app/serializers/alchemy/essence_richtext_serializer.rb delete mode 100644 app/serializers/alchemy/essence_select_serializer.rb delete mode 100644 app/serializers/alchemy/essence_text_serializer.rb delete mode 100644 app/views/alchemy/admin/contents/create.js.erb delete mode 100644 app/views/alchemy/admin/essence_audios/edit.html.erb delete mode 100644 app/views/alchemy/admin/essence_files/edit.html.erb delete mode 100644 app/views/alchemy/admin/essence_pictures/destroy.js.erb delete mode 100644 app/views/alchemy/admin/essence_pictures/edit.html.erb delete mode 100644 app/views/alchemy/admin/essence_pictures/save_link.js.erb delete mode 100644 app/views/alchemy/admin/essence_pictures/update.js.erb delete mode 100644 app/views/alchemy/admin/essence_videos/edit.html.erb delete mode 100644 app/views/alchemy/essences/_essence_audio_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_audio_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_boolean_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_boolean_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_date_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_date_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_file_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_file_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_headline_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_headline_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_html_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_html_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_link_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_link_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_node_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_node_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_page_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_page_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_picture_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_picture_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_richtext_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_richtext_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_select_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_select_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_text_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_text_view.html.erb delete mode 100644 app/views/alchemy/essences/_essence_video_editor.html.erb delete mode 100644 app/views/alchemy/essences/_essence_video_view.html.erb delete mode 100644 app/views/alchemy/essences/shared/_essence_picture_tools.html.erb delete mode 100644 app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb delete mode 100644 db/migrate/20200423073425_create_alchemy_essence_nodes.rb delete mode 100644 db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb delete mode 100644 db/migrate/20210406093436_add_alchemy_essence_headlines.rb delete mode 100644 db/migrate/20210506135919_create_essence_audios.rb delete mode 100644 db/migrate/20210506140258_create_essence_videos.rb delete mode 100644 db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb delete mode 100644 lib/alchemy/essence.rb delete mode 100644 lib/alchemy/test_support/essence_shared_examples.rb delete mode 100644 lib/alchemy/test_support/factories/content_factory.rb delete mode 100644 lib/alchemy/test_support/factories/essence_audio_factory.rb delete mode 100644 lib/alchemy/test_support/factories/essence_file_factory.rb delete mode 100644 lib/alchemy/test_support/factories/essence_page_factory.rb delete mode 100644 lib/alchemy/test_support/factories/essence_picture_factory.rb delete mode 100644 lib/alchemy/test_support/factories/essence_text_factory.rb delete mode 100644 lib/alchemy/test_support/factories/essence_video_factory.rb delete mode 100644 lib/alchemy/upgrader/tasks/ingredients_migrator.rb delete mode 100644 lib/generators/alchemy/essence/essence_generator.rb delete mode 100644 lib/generators/alchemy/essence/templates/editor.html.erb delete mode 100644 lib/generators/alchemy/essence/templates/view.html.erb delete mode 100644 spec/controllers/alchemy/admin/essence_audios_controller_spec.rb delete mode 100644 spec/controllers/alchemy/admin/essence_files_controller_spec.rb delete mode 100644 spec/controllers/alchemy/admin/essence_pictures_controller_spec.rb delete mode 100644 spec/controllers/alchemy/admin/essence_videos_controller_spec.rb delete mode 100644 spec/controllers/alchemy/api/contents_controller_spec.rb delete mode 100644 spec/decorators/alchemy/content_editor_spec.rb delete mode 100644 spec/dummy/app/models/dummy_model.rb delete mode 100644 spec/dummy/db/migrate/20150412103152_create_dummy_model.rb delete mode 120000 spec/dummy/db/migrate/20200226213334_alchemy_four_point_four.rb delete mode 120000 spec/dummy/db/migrate/20200423073425_create_alchemy_essence_nodes.rb delete mode 120000 spec/dummy/db/migrate/20200504210159_remove_site_id_from_nodes.rb delete mode 120000 spec/dummy/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb delete mode 120000 spec/dummy/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb delete mode 120000 spec/dummy/db/migrate/20200514091507_make_page_layoutpage_null_false.rb delete mode 120000 spec/dummy/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb delete mode 120000 spec/dummy/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb delete mode 120000 spec/dummy/db/migrate/20200907111332_remove_tri_state_booleans.rb delete mode 120000 spec/dummy/db/migrate/20201207131309_create_page_versions.rb delete mode 120000 spec/dummy/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb delete mode 120000 spec/dummy/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb delete mode 120000 spec/dummy/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb delete mode 120000 spec/dummy/db/migrate/20210406093436_add_alchemy_essence_headlines.rb delete mode 120000 spec/dummy/db/migrate/20210506135919_create_essence_audios.rb delete mode 120000 spec/dummy/db/migrate/20210506140258_create_essence_videos.rb delete mode 120000 spec/dummy/db/migrate/20210508091432_create_alchemy_ingredients.rb delete mode 100644 spec/dummy/db/migrate/20220831084620_add_playsinline_to_alchemy_essence_videos.alchemy.rb rename spec/dummy/db/migrate/{20191129235819_gutentag_tables.gutentag.rb => 20230119091654_gutentag_tables.gutentag.rb} (78%) rename spec/dummy/db/migrate/{20191129235820_gutentag_cache_counter.gutentag.rb => 20230119091655_gutentag_cache_counter.gutentag.rb} (64%) rename spec/dummy/db/migrate/{20191129235821_no_null_counters.gutentag.rb => 20230119091656_no_null_counters.gutentag.rb} (70%) create mode 100644 spec/dummy/db/migrate/20230119091717_alchemy_four_point_four.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091718_remove_site_id_from_nodes.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091719_add_language_id_foreign_key_to_alchemy_pages.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091720_add_menu_type_to_alchemy_nodes.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091721_make_page_layoutpage_null_false.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091722_remove_visible_from_alchemy_pages.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091723_create_alchemy_picture_thumbs.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091724_remove_tri_state_booleans.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091725_create_page_versions.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091726_add_page_version_id_to_alchemy_elements.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091727_rename_public_on_and_public_until_on_alchemy_pages.alchemy.rb create mode 100644 spec/dummy/db/migrate/20230119091728_create_alchemy_ingredients.alchemy.rb rename spec/dummy/db/migrate/{20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb => 20230119091729_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.alchemy.rb} (81%) delete mode 100644 spec/helpers/alchemy/admin/contents_helper_spec.rb delete mode 100644 spec/helpers/alchemy/admin/essences_helper_spec.rb delete mode 100644 spec/libraries/alchemy/upgrader/tasks/ingredients_migrator_spec.rb delete mode 100644 spec/models/alchemy/content_spec.rb delete mode 100644 spec/models/alchemy/essence_audio_spec.rb delete mode 100644 spec/models/alchemy/essence_boolean_spec.rb delete mode 100644 spec/models/alchemy/essence_date_spec.rb delete mode 100644 spec/models/alchemy/essence_file_spec.rb delete mode 100644 spec/models/alchemy/essence_headline_spec.rb delete mode 100644 spec/models/alchemy/essence_html_spec.rb delete mode 100644 spec/models/alchemy/essence_link_spec.rb delete mode 100644 spec/models/alchemy/essence_node_spec.rb delete mode 100644 spec/models/alchemy/essence_page_spec.rb delete mode 100644 spec/models/alchemy/essence_picture_spec.rb delete mode 100644 spec/models/alchemy/essence_picture_view_spec.rb delete mode 100644 spec/models/alchemy/essence_richtext_spec.rb delete mode 100644 spec/models/alchemy/essence_select_spec.rb delete mode 100644 spec/models/alchemy/essence_text_spec.rb delete mode 100644 spec/models/alchemy/essence_video_spec.rb delete mode 100644 spec/models/dummy_model_spec.rb delete mode 100644 spec/requests/alchemy/admin/contents_controller_spec.rb delete mode 100644 spec/views/alchemy/admin/essence_pictures/edit_spec.rb delete mode 100644 spec/views/essences/essence_audio_editor_spec.rb delete mode 100644 spec/views/essences/essence_audio_view_spec.rb delete mode 100644 spec/views/essences/essence_boolean_editor_spec.rb delete mode 100644 spec/views/essences/essence_boolean_view_spec.rb delete mode 100644 spec/views/essences/essence_date_editor_spec.rb delete mode 100644 spec/views/essences/essence_date_view_spec.rb delete mode 100644 spec/views/essences/essence_file_editor_spec.rb delete mode 100644 spec/views/essences/essence_file_view_spec.rb delete mode 100644 spec/views/essences/essence_html_view_spec.rb delete mode 100644 spec/views/essences/essence_link_editor_spec.rb delete mode 100644 spec/views/essences/essence_link_view_spec.rb delete mode 100644 spec/views/essences/essence_page_editor_spec.rb delete mode 100644 spec/views/essences/essence_page_view_spec.rb delete mode 100644 spec/views/essences/essence_picture_editor_spec.rb delete mode 100644 spec/views/essences/essence_picture_view_spec.rb delete mode 100644 spec/views/essences/essence_richtext_view_spec.rb delete mode 100644 spec/views/essences/essence_select_editor_spec.rb delete mode 100644 spec/views/essences/essence_select_view_spec.rb delete mode 100644 spec/views/essences/essence_text_editor_spec.rb delete mode 100644 spec/views/essences/essence_text_view_spec.rb delete mode 100644 spec/views/essences/essence_video_editor_spec.rb delete mode 100644 spec/views/essences/essence_video_view_spec.rb diff --git a/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee b/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee index 46360457ea..98adceb1c5 100644 --- a/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +++ b/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee @@ -20,7 +20,7 @@ $.extend Alchemy, setElementClean: (element) -> $element = $(element) $element.removeClass('dirty') - $element.find('> .element-content .dirty').removeClass('dirty') + $element.find('> .element-body .dirty').removeClass('dirty') window.onbeforeunload = undefined isPageDirty: -> diff --git a/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee b/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee index 03dfff8d6a..7bc5dab396 100644 --- a/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +++ b/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee @@ -15,7 +15,7 @@ Alchemy.ElementEditors = init: -> @element_area = $("#element_area") @bindEvents() - @expandContentGroups() + @expandIngredientGroups() return # Binds click events on several DOM elements from element editors @@ -29,27 +29,25 @@ Alchemy.ElementEditors = @onDoubleClickElement(e) @element_area.on "click", "[data-element-toggle]", (e) => @onClickToggle(e) - @element_area.on "click", '[data-create-missing-content]', (e) => - @onClickMissingContent(e) # Binds the custom FocusElementEditor event @element_area.on "FocusElementEditor.Alchemy", '.element-editor', (e) => @onFocusElement(e) # Binds the custom SaveElement event @element_area.on "SaveElement.Alchemy", '.element-editor', (e, data) => @onSaveElement(e, data) - @element_area.on "click", '[data-toggle-content-group]', (e) => - @onToggleContentGroup(e) + @element_area.on "click", '[data-toggle-ingredient-group]', (e) => + @onToggleIngredientGroup(e) # Listen to postMessage messages from the preview frame window.addEventListener 'message', (e) => @onMessage(e.data) true return - # Expands content groups that are stored in sessionStorage as expanded - expandContentGroups: -> - if $expanded_content_groups = sessionStorage.getItem('Alchemy.expanded_content_groups') - for header_id in JSON.parse($expanded_content_groups) then do (header_id) => - $('#' + header_id).closest('.content-group').addClass('expanded'); + # Expands ingredient groups that are stored in sessionStorage as expanded + expandIngredientGroups: -> + if $expanded_ingredient_groups = sessionStorage.getItem('Alchemy.expanded_ingredient_groups') + for header_id in JSON.parse($expanded_ingredient_groups) then do (header_id) => + $('#' + header_id).closest('.ingredient-group').addClass('expanded'); # Selects and scrolls to element with given id in the preview window. # @@ -179,21 +177,21 @@ Alchemy.ElementEditors = Alchemy.Buttons.enable($element) true - # Toggle visibility of the content fields in the group - onToggleContentGroup: (event) -> - $group_div = $(event.currentTarget).closest('.content-group'); + # Toggle visibility of the ingredient fields in the group + onToggleIngredientGroup: (event) -> + $group_div = $(event.currentTarget).closest('.ingredient-group'); $group_div.toggleClass('expanded'); - $expanded_content_groups = JSON.parse(sessionStorage.getItem('Alchemy.expanded_content_groups') || '[]'); - # Add or remove depending on whether this content group is expanded + $expanded_ingredient_groups = JSON.parse(sessionStorage.getItem('Alchemy.expanded_ingredient_groups') || '[]'); + # Add or remove depending on whether this ingredient group is expanded if $group_div.hasClass('expanded') - if $expanded_content_groups.indexOf(event.currentTarget.id) == -1 - $expanded_content_groups.push(event.currentTarget.id); + if $expanded_ingredient_groups.indexOf(event.currentTarget.id) == -1 + $expanded_ingredient_groups.push(event.currentTarget.id); else - $expanded_content_groups = $expanded_content_groups.filter (value) -> + $expanded_ingredient_groups = $expanded_ingredient_groups.filter (value) -> value != event.currentTarget.id - sessionStorage.setItem('Alchemy.expanded_content_groups', JSON.stringify($expanded_content_groups)) + sessionStorage.setItem('Alchemy.expanded_ingredient_groups', JSON.stringify($expanded_ingredient_groups)) false # Event handlers @@ -248,22 +246,10 @@ Alchemy.ElementEditors = e.stopPropagation() false - # Handles the missing content button click events. - # - # Ensures that the links query string is converted into post body and send - # the request via a real ajax post to server, to allow long query strings. - # - onClickMissingContent: (e) -> - link = e.target - url = link.pathname - querystring = link.search.replace(/\?/, '') - $.post(url, querystring) - false - # private _shouldUpdateTitle: (element, event) -> - editors = element.find('> .element-content .element-content-editors, > .element-content .element-ingredient-editors').children() + editors = element.find('> .element-body .element-ingredient-editors').children() if @_hasParents(element) editors.length != 0 else if @_isParent(element) && @_isFirstChild $(event.target) diff --git a/app/assets/stylesheets/alchemy/elements.scss b/app/assets/stylesheets/alchemy/elements.scss index 8282d3a597..3412767d90 100644 --- a/app/assets/stylesheets/alchemy/elements.scss +++ b/app/assets/stylesheets/alchemy/elements.scss @@ -275,11 +275,10 @@ } } - .element-content { + .element-body { margin: 4px 8px; } - .content_editor, .ingredient-editor, .picture_thumbnail { width: 100%; @@ -303,7 +302,7 @@ } } - .element-content { + .element-body { margin: 2 * $default-padding; } @@ -414,7 +413,7 @@ } } -.content-group { +.ingredient-group { width: 100%; padding: $default-padding 0; position: relative; @@ -425,7 +424,7 @@ padding-bottom: 0; } - .content-group-header { + .ingredient-group-header { display: flex; align-items: center; justify-content: space-between; @@ -434,22 +433,21 @@ padding: $default-padding 1px; } - .content-group-contents { + .ingredient-group-ingredients { display: none; } &.expanded { - .content-group-contents { + .ingredient-group-ingredients { display: block; } - .content-group-expand { + .ingredient-group-expand { @extend .fa-angle-up; } } } -.element-content-editors, .element-ingredient-editors { display: flex; flex-wrap: wrap; @@ -639,9 +637,6 @@ } } -.content_editor.essence_audio, -.content_editor.essence_file, -.content_editor.essence_video, .ingredient-editor.audio, .ingredient-editor.file, .ingredient-editor.video { @@ -717,7 +712,6 @@ select.long { padding: 0; } -.content_editor, .ingredient-editor { width: 100%; padding: $default-padding 0; @@ -885,10 +879,6 @@ select.long { } } -.content_rtf_text_area { - display: none; -} - div.pictures_for_element { overflow: auto; margin-top: 4px; @@ -928,8 +918,6 @@ textarea.has_tinymce { } } -.content_editor .hint-with-icon, -.content_editor .with-hint, .ingredient-editor .hint-with-icon, .ingredient-editor .with-hint, .element-handle .hint-with-icon { @@ -946,7 +934,7 @@ textarea.has_tinymce { } .is-fixed { - &.with-contents { + &.with-ingredients { > .element-footer { border-top: 0; border-bottom: 1px solid $medium-gray; diff --git a/app/controllers/alchemy/admin/contents_controller.rb b/app/controllers/alchemy/admin/contents_controller.rb deleted file mode 100644 index 13b460dc69..0000000000 --- a/app/controllers/alchemy/admin/contents_controller.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - module Admin - class ContentsController < Alchemy::Admin::BaseController - helper "alchemy/admin/essences" - - authorize_resource class: Alchemy::Content - - def create - @content = Content.create(content_params) - end - - private - - def content_params - params.require(:content).permit(:element_id, :name, :ingredient) - end - end - end -end diff --git a/app/controllers/alchemy/admin/elements_controller.rb b/app/controllers/alchemy/admin/elements_controller.rb index 568c71c4eb..13277e3658 100644 --- a/app/controllers/alchemy/admin/elements_controller.rb +++ b/app/controllers/alchemy/admin/elements_controller.rb @@ -56,15 +56,16 @@ def create def update @page = @element.page - if element_params.key?(:ingredients_attributes) - update_element_with_ingredients + if @element.update(element_params) + @element_validated = true else - update_element_with_contents + element_update_error + @error_messages = @element.ingredient_error_messages end end def destroy - @richtext_ids = @element.richtext_contents_ids + @element.richtext_ingredients_ids + @richtext_ids = @element.richtext_ingredients_ids @element.destroy @notice = Alchemy.t("Successfully deleted element") % { element: @element.display_name } end @@ -103,14 +104,12 @@ def fold def element_includes [ { - contents: :essence, ingredients: :related_object, }, :tags, { all_nested_elements: [ { - contents: :essence, ingredients: :related_object, }, :tags, @@ -130,9 +129,9 @@ def load_clipboard_items def element_from_clipboard @element_from_clipboard ||= begin - @clipboard = get_clipboard("elements") - @clipboard.detect { |item| item["id"].to_i == params[:paste_from_clipboard].to_i } - end + @clipboard = get_clipboard("elements") + @clipboard.detect { |item| item["id"].to_i == params[:paste_from_clipboard].to_i } + end end def paste_element_from_clipboard @@ -152,10 +151,6 @@ def paste_element_from_clipboard element end - def contents_params - params.fetch(:contents, {}).permit! - end - def element_params params.fetch(:element, {}).permit(:tag_list, ingredients_attributes: {}) end @@ -164,24 +159,6 @@ def create_element_params params.require(:element).permit(:name, :page_version_id, :parent_element_id) end - def update_element_with_ingredients - if @element.update(element_params) - @element_validated = true - else - element_update_error - @error_messages = @element.ingredient_error_messages - end - end - - def update_element_with_contents - if @element.update_contents(contents_params) - @element_validated = @element.update(element_params) - else - element_update_error - @error_messages = @element.essence_error_messages - end - end - def element_update_error @element_validated = false @notice = Alchemy.t("Validation failed") diff --git a/app/controllers/alchemy/admin/essence_audios_controller.rb b/app/controllers/alchemy/admin/essence_audios_controller.rb deleted file mode 100644 index 8bfedc8fa7..0000000000 --- a/app/controllers/alchemy/admin/essence_audios_controller.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - module Admin - class EssenceAudiosController < Alchemy::Admin::BaseController - authorize_resource class: Alchemy::EssenceAudio - before_action :load_essence - - def update - @essence_audio.update(essence_audio_params) - end - - private - - def load_essence - @essence_audio = EssenceAudio.find(params[:id]) - end - - def essence_audio_params - params.require(:essence_audio).permit( - :autoplay, - :controls, - :loop, - :muted, - :attachment_id - ) - end - end - end -end diff --git a/app/controllers/alchemy/admin/essence_files_controller.rb b/app/controllers/alchemy/admin/essence_files_controller.rb deleted file mode 100644 index e12f8d279a..0000000000 --- a/app/controllers/alchemy/admin/essence_files_controller.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - module Admin - class EssenceFilesController < Alchemy::Admin::BaseController - authorize_resource class: Alchemy::EssenceFile - - before_action :load_essence_file, only: [:edit, :update] - - helper "Alchemy::Admin::Contents" - - def edit - @content = @essence_file.content - end - - def update - @essence_file.update(essence_file_params) - end - - private - - def essence_file_params - params.require(:essence_file).permit(:title, :css_class, :link_text) - end - - def load_essence_file - @essence_file = EssenceFile.find(params[:id]) - end - end - end -end diff --git a/app/controllers/alchemy/admin/essence_pictures_controller.rb b/app/controllers/alchemy/admin/essence_pictures_controller.rb deleted file mode 100644 index 95769647fd..0000000000 --- a/app/controllers/alchemy/admin/essence_pictures_controller.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - module Admin - class EssencePicturesController < Alchemy::Admin::BaseController - include CropAction - - authorize_resource class: Alchemy::EssencePicture - - before_action :load_essence_picture, only: [:edit, :update] - before_action :load_content, only: [:edit, :update] - - helper "alchemy/admin/contents" - helper "alchemy/admin/essences" - helper "alchemy/url" - - def edit - end - - def update - @essence_picture.update(essence_picture_params) - end - - private - - def load_essence_picture - @essence_picture = EssencePicture.find(params[:id]) - end - - def load_croppable_resource - @croppable_resource = EssencePicture.find(params[:id]) - end - - def load_content - @content = Content.find(params[:content_id]) - end - - def essence_picture_params - params.require(:essence_picture).permit(:alt_tag, :caption, :css_class, :render_size, :title, :crop_from, :crop_size) - end - end - end -end diff --git a/app/controllers/alchemy/admin/essence_videos_controller.rb b/app/controllers/alchemy/admin/essence_videos_controller.rb deleted file mode 100644 index 4315acc95e..0000000000 --- a/app/controllers/alchemy/admin/essence_videos_controller.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - module Admin - class EssenceVideosController < Alchemy::Admin::BaseController - authorize_resource class: Alchemy::EssenceVideo - before_action :load_essence - - def update - @essence_video.update(essence_video_params) - end - - private - - def load_essence - @essence_video = EssenceVideo.find(params[:id]) - end - - def essence_video_params - params.require(:essence_video).permit( - :width, - :height, - :autoplay, - :controls, - :loop, - :muted, - :playsinline, - :preload, - :attachment_id - ) - end - end - end -end diff --git a/app/controllers/alchemy/admin/pictures_controller.rb b/app/controllers/alchemy/admin/pictures_controller.rb index e861215a7b..9ebf49e3cc 100644 --- a/app/controllers/alchemy/admin/pictures_controller.rb +++ b/app/controllers/alchemy/admin/pictures_controller.rb @@ -32,7 +32,7 @@ def show @query = Picture.ransack(params[:q]) @previous = filtered_pictures.where("name < ?", @picture.name).last @next = filtered_pictures.where("name > ?", @picture.name).first - @assignments = @picture.essence_pictures.joins(content: { element: :page }) + @assignments = @picture.picture_ingredients.joins(element: :page) render action: "show" end diff --git a/app/controllers/alchemy/api/contents_controller.rb b/app/controllers/alchemy/api/contents_controller.rb deleted file mode 100644 index ee4a1dc227..0000000000 --- a/app/controllers/alchemy/api/contents_controller.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class Api::ContentsController < Api::BaseController - # Returns all contents as json object - # - # You can either load all or only these for :element_id param - # - def index - # Fix for cancancan not able to merge multiple AR scopes for logged in users - if can? :manage, Alchemy::Content - @contents = Content.all - else - @contents = Content.accessible_by(current_ability, :index) - end - if params[:element_id].present? - @contents = @contents.where(element_id: params[:element_id]) - end - @contents = @contents.includes(*content_includes) - - render json: @contents, adapter: :json, root: "contents" - end - - # Returns a json object for content - # - # You can either load it from :id param - # or even more useful via passing the element id and the name of the content - # - # $ bin/rake routes - # - # for more infos on how the url looks like. - # - def show - if params[:id] - @content = Content.where(id: params[:id]).includes(:essence).first - elsif params[:element_id] && params[:name] - @content = Content.where( - element_id: params[:element_id], - name: params[:name], - ).includes(*content_includes).first || raise(ActiveRecord::RecordNotFound) - end - authorize! :show, @content - respond_with @content - end - - private - - def content_includes - %i[essence] - end - end -end diff --git a/app/controllers/alchemy/api/elements_controller.rb b/app/controllers/alchemy/api/elements_controller.rb index 168c242e0a..2a9c424473 100644 --- a/app/controllers/alchemy/api/elements_controller.rb +++ b/app/controllers/alchemy/api/elements_controller.rb @@ -47,14 +47,12 @@ def element_includes { nested_elements: [ { - contents: :essence, ingredients: :related_object, }, :tags, ], }, { - contents: :essence, ingredients: :related_object, }, :tags, diff --git a/app/decorators/alchemy/content_editor.rb b/app/decorators/alchemy/content_editor.rb deleted file mode 100644 index aef2b92d55..0000000000 --- a/app/decorators/alchemy/content_editor.rb +++ /dev/null @@ -1,119 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class ContentEditor < SimpleDelegator - alias_method :content, :__getobj__ - - def to_partial_path - "alchemy/essences/#{essence_partial_name}_editor" - end - - def css_classes - [ - "content_editor", - essence_partial_name, - deprecated? ? "deprecated" : nil, - ].compact - end - - def data_attributes - { - content_id: id, - content_name: name, - } - end - - # Returns a string to be passed to Rails form field tags to ensure we have same params layout everywhere. - # - # === Example: - # - # <%= text_field_tag content_editor.form_field_name, content_editor.ingredient %> - # - # === Options: - # - # You can pass an Essence column_name. Default is 'ingredient' - # - # ==== Example: - # - # <%= text_field_tag content_editor.form_field_name(:link), content_editor.ingredient %> - # - def form_field_name(essence_column = "ingredient") - "contents[#{id}][#{essence_column}]" - end - - def form_field_id(essence_column = "ingredient") - "contents_#{id}_#{essence_column}" - end - - # Fixes Rails partial renderer calling to_model on the object - # which reveals the delegated content instead of this decorator. - def respond_to?(method_name) - return false if method_name == :to_model - - super - end - - def has_warnings? - definition.blank? || deprecated? - end - - def warnings - return unless has_warnings? - - if definition.blank? - Logger.warn("Content #{name} is missing its definition", caller(1..1)) - Alchemy.t(:content_definition_missing) - else - deprecation_notice - end - end - - # Returns a deprecation notice for contents marked deprecated - # - # You can either use localizations or pass a String as notice - # in the content definition. - # - # == Custom deprecation notices - # - # Use general content deprecation notice - # - # - name: element_name - # contents: - # - name: old_content - # type: EssenceText - # deprecated: true - # - # Add a translation to your locale file for a per content notice. - # - # en: - # alchemy: - # content_deprecation_notices: - # element_name: - # old_content: Foo baz widget is deprecated - # - # or use the global translation that apply to all deprecated contents. - # - # en: - # alchemy: - # content_deprecation_notice: Foo baz widget is deprecated - # - # or pass string as deprecation notice. - # - # - name: element_name - # contents: - # - name: old_content - # type: EssenceText - # deprecated: This content will be removed soon. - # - def deprecation_notice - case definition["deprecated"] - when String - definition["deprecated"] - when TrueClass - Alchemy.t(name, - scope: [:content_deprecation_notices, element.name], - default: Alchemy.t(:content_deprecated)) - end - end - end -end diff --git a/app/decorators/alchemy/element_editor.rb b/app/decorators/alchemy/element_editor.rb index 002434b1f9..bef7280b0c 100644 --- a/app/decorators/alchemy/element_editor.rb +++ b/app/decorators/alchemy/element_editor.rb @@ -8,17 +8,6 @@ def to_partial_path "alchemy/admin/elements/element" end - # Returns content editor instances for defined contents - # - # Creates contents on demand if the content is not yet present on the element - # - # @return Array - def contents - element.definition.fetch(:contents, []).map do |content| - Alchemy::ContentEditor.new(find_or_create_content(content[:name])) - end - end - # Returns ingredient editor instances for defined ingredients # # Creates ingredient on demand if the ingredient is not yet present on the element @@ -63,7 +52,7 @@ def translated_group(group) def css_classes [ "element-editor", - content_definitions.present? ? "with-contents" : "without-contents", + ingredient_definitions.present? ? "with-ingredients" : "without-ingredients", nestable_elements.any? ? "nestable" : "not-nestable", taggable? ? "taggable" : "not-taggable", folded ? "folded" : "expanded", @@ -78,7 +67,7 @@ def css_classes def editable? return false if folded? - content_definitions.present? || ingredient_definitions.any? || taggable? + ingredient_definitions.any? || taggable? end # Fixes Rails partial renderer calling to_model on the object diff --git a/app/helpers/alchemy/admin/contents_helper.rb b/app/helpers/alchemy/admin/contents_helper.rb deleted file mode 100644 index b8faa066e1..0000000000 --- a/app/helpers/alchemy/admin/contents_helper.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - module Admin - module ContentsHelper - include Alchemy::Admin::BaseHelper - - # Renders the name of elements content. - # - # Displays a warning icon if content is missing its definition. - # - # Displays a mandatory field indicator, if the content has validations. - # - def render_content_name(content) - if content.blank? - warning("Content is nil") - return - end - - content_name = content.name_for_label - - if content.has_warnings? - icon = hint_with_tooltip(content.warnings) - content_name = "#{icon} #{content_name}".html_safe - end - - if content.has_validations? - "#{content_name}*".html_safe - else - content_name - end - end - - # Renders the label and a remove link for a content. - def content_label(content) - content_tag :label, for: content.form_field_id do - [render_content_name(content), render_hint_for(content)].compact.join(" ").html_safe - end - end - end - end -end diff --git a/app/helpers/alchemy/admin/elements_helper.rb b/app/helpers/alchemy/admin/elements_helper.rb index 2c426040e5..0fe88175aa 100644 --- a/app/helpers/alchemy/admin/elements_helper.rb +++ b/app/helpers/alchemy/admin/elements_helper.rb @@ -4,8 +4,6 @@ module Alchemy module Admin module ElementsHelper include Alchemy::Admin::IngredientsHelper - include Alchemy::Admin::ContentsHelper - include Alchemy::Admin::EssencesHelper # Returns an elements array for select helper. # diff --git a/app/helpers/alchemy/admin/essences_helper.rb b/app/helpers/alchemy/admin/essences_helper.rb deleted file mode 100644 index 52f0fbbeca..0000000000 --- a/app/helpers/alchemy/admin/essences_helper.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - module Admin - module EssencesHelper - # Renders a thumbnail for given EssencePicture content with correct cropping and size - def essence_picture_thumbnail(content) - picture = content.ingredient - essence = content.essence - - return if picture.nil? - - image_tag( - essence.thumbnail_url, - alt: picture.name, - class: "img_paddingtop", - title: Alchemy.t(:image_name, name: picture.name), - ) - end - - # Size value for edit picture dialog - def edit_picture_dialog_size(content) - if content.settings[:caption_as_textarea] - content.settings[:sizes] ? "380x320" : "380x300" - else - content.settings[:sizes] ? "380x290" : "380x255" - end - end - end - end -end diff --git a/app/helpers/alchemy/elements_block_helper.rb b/app/helpers/alchemy/elements_block_helper.rb index 308ce872b4..59d0859751 100644 --- a/app/helpers/alchemy/elements_block_helper.rb +++ b/app/helpers/alchemy/elements_block_helper.rb @@ -24,69 +24,32 @@ def element # Block-level helper class for element views. # class ElementViewHelper < BlockHelper - # Renders one of the element's contents. + # Renders one of the element's ingredients. # # If the element uses +ingredients+ it renders the ingredient record. # def render(name, options = {}, html_options = {}) - renderable = element.ingredient_by_role(name) || Alchemy::Deprecation.silence { content(name) } + renderable = element.ingredient_by_role(name) return if renderable.nil? - if Alchemy::DEPRECATED_ESSENCE_CLASSES.include?(renderable.try(:essence)&.class&.name) - Alchemy::Deprecation.warn( - "Using a '#{renderable.essence.class.name.demodulize}' content is deprecated. " \ - "Please use a '#{Alchemy::DEPRECATED_ESSENCE_CLASS_MAPPING[renderable.essence.class.name].demodulize}' ingredient instead." - ) - end - helpers.render(renderable, { options: options, html_options: html_options, }) end - # Returns one of the element's contents (ie. essence instances). - # - def content(name) - element.content_by_name(name) - end - - deprecate content: "Use `ingredient_by_role` instead", deprecator: Alchemy::Deprecation - - # Returns the ingredient of one of the element's contents. - # - # If the element uses +ingredients+ it returns the +value+ of the ingredient record. - # - def ingredient(name) - element.ingredient(name) - end - # Returns the value of one of the element's ingredients. # def value(name) element.value_for(name) end - # Returns true if the given content or ingredient has a value. + # Returns true if the given ingredient has a value. # def has?(name) - if element.ingredient_definitions.any? - element.has_value_for?(name) - else - Alchemy::Deprecation.silence do - element.has_ingredient?(name) - end - end + element.has_value_for?(name) end - # Return's the given content's essence. - # - def essence(name) - content(name).try(:essence) - end - - deprecate essence: "Use `ingredient_by_role` instead", deprecator: Alchemy::Deprecation - # Return's the ingredient record by given role. # def ingredient_by_role(role) diff --git a/app/models/alchemy/attachment.rb b/app/models/alchemy/attachment.rb index 3da4e97daa..a51300667e 100644 --- a/app/models/alchemy/attachment.rb +++ b/app/models/alchemy/attachment.rb @@ -30,9 +30,12 @@ class Attachment < BaseRecord stampable stamper_class_name: Alchemy.user_class.name - has_many :essence_files, class_name: "Alchemy::EssenceFile", foreign_key: "attachment_id" - has_many :contents, through: :essence_files - has_many :elements, through: :contents + has_many :file_ingredients, + class_name: "Alchemy::Ingredients::File", + foreign_key: "related_object_id", + inverse_of: :related_object + + has_many :elements, through: :file_ingredients has_many :pages, through: :elements scope :by_file_type, ->(file_type) { where(file_mime_type: file_type) } diff --git a/app/models/alchemy/content.rb b/app/models/alchemy/content.rb deleted file mode 100644 index 86252fd9ae..0000000000 --- a/app/models/alchemy/content.rb +++ /dev/null @@ -1,247 +0,0 @@ -# frozen_string_literal: true - -# == Schema Information -# -# Table name: alchemy_contents -# -# id :integer not null, primary key -# name :string -# essence_type :string not null -# essence_id :integer not null -# element_id :integer not null -# position :integer -# created_at :datetime not null -# updated_at :datetime not null -# creator_id :integer -# updater_id :integer -# - -require_dependency "alchemy/content/factory" - -module Alchemy - # @deprecated - class Content < BaseRecord - include Alchemy::Logger - include Alchemy::Hints - - # Concerns - include Factory - - belongs_to :essence, polymorphic: true, dependent: :destroy, inverse_of: :content - belongs_to :element, touch: true, inverse_of: :contents - has_one :page, through: :element - - # Essence scopes - scope :essence_booleans, -> { where(essence_type: "Alchemy::EssenceBoolean") } - scope :essence_dates, -> { where(essence_type: "Alchemy::EssenceDate") } - scope :essence_files, -> { where(essence_type: "Alchemy::EssenceFile") } - scope :essence_htmls, -> { where(essence_type: "Alchemy::EssenceHtml") } - scope :essence_links, -> { where(essence_type: "Alchemy::EssenceLink") } - scope :essence_pictures, -> { where(essence_type: "Alchemy::EssencePicture") } - scope :essence_richtexts, -> { where(essence_type: "Alchemy::EssenceRichtext") } - scope :essence_selects, -> { where(essence_type: "Alchemy::EssenceSelect") } - scope :essence_texts, -> { where(essence_type: "Alchemy::EssenceText") } - scope :named, ->(name) { where(name: name) } - scope :available, -> { published } - scope :published, -> { joins(:element).merge(Element.published) } - scope :not_restricted, -> { joins(:element).merge(Element.not_restricted) } - - delegate :restricted?, to: :page, allow_nil: true - delegate :public?, to: :element, allow_nil: true - - class << self - # Returns the translated label for a content name. - # - # Translate it in your locale yml file: - # - # alchemy: - # content_names: - # foo: Bar - # - # Optionally you can scope your content name to an element: - # - # alchemy: - # content_names: - # article: - # foo: Baz - # - def translated_label_for(content_name, element_name = nil) - Alchemy.t( - content_name, - scope: "content_names.#{element_name}", - default: Alchemy.t("content_names.#{content_name}", default: content_name.humanize), - ) - end - end - - # The content's view partial is dependent from its name - # - # == Define contents - # - # Contents are defined in the +config/alchemy/elements.yml+ file - # - # - name: article - # contents: - # - name: headline - # type: EssenceText - # - # == Override the view - # - # Content partials live in +app/views/alchemy/essences+ - # - def to_partial_path - "alchemy/essences/#{essence_partial_name}_view" - end - - # Settings from the elements.yml definition - def settings - return {} if definition.blank? - - @settings ||= definition.fetch(:settings, {}) - end - - # Fetches value from settings - # - # @param key [Symbol] - The hash key you want to fetch the value from - # @param options [Hash] - An optional Hash that can override the settings. - # Normally passed as options hash into the content - # editor view. - def settings_value(key, options = {}) - settings.update(options || {}).symbolize_keys[key.to_sym] - end - - def siblings - return [] if !element - - element.contents - end - - # Gets the ingredient from essence - def ingredient - return nil if essence.nil? - - essence.ingredient - end - - # Serialized object representation for json api - # - def serialize - { - name: name, - value: serialized_ingredient, - link: essence.try(:link), - }.delete_if { |_k, v| v.blank? } - end - - # Ingredient value from essence for json api - # - # If the essence responds to +serialized_ingredient+ method it takes this - # otherwise it uses the ingredient column. - # - def serialized_ingredient - essence.try(:serialized_ingredient) || ingredient - end - - # Sets the ingredient from essence - def ingredient=(value) - raise EssenceMissingError if essence.nil? - - essence.ingredient = value - end - - # Updates the essence. - # - # Called from +Alchemy::Element#update_contents+ - # - # Adds errors to self.base if essence validation fails. - # - def update_essence(params = {}) - raise EssenceMissingError if essence.nil? - - if essence.update(params) - true - else - errors.add(:essence, :validation_failed) - false - end - end - - def essence_validation_failed? - essence.errors.any? - end - - def has_validations? - definition["validate"].present? - end - - # Returns a string used as dom id on html elements. - def dom_id - return "" if essence.nil? - - "#{essence_partial_name}_#{id}" - end - - # Returns the translated name for displaying in labels, etc. - def name_for_label - self.class.translated_label_for(name, element.name) - end - - def linked? - essence && !essence.link.blank? - end - - def deprecated? - !!definition["deprecated"] - end - - # Returns true if this content should be taken for element preview. - def preview_content? - !!definition["as_element_title"] - end - - # Proxy method that returns the preview text from essence. - # - def preview_text(maxlength = 30) - essence.preview_text(maxlength) - end - - def essence_partial_name - return "" if essence.nil? - - essence.partial_name - end - - def normalized_essence_type - self.class.normalize_essence_type(essence_type) - end - - # Returns true if there is a tinymce setting defined on the content definiton - # or if the +essence.has_tinymce?+ returns true. - def has_tinymce? - settings[:tinymce].present? || (essence.present? && essence.has_tinymce?) - end - - # Returns true if there is a tinymce setting defined that contains settings. - def has_custom_tinymce_config? - settings[:tinymce].is_a?(Hash) - end - - # Returns css class names for the content textarea. - def tinymce_class_name - "has_tinymce" + (has_custom_tinymce_config? ? " #{element.name}_#{name}" : "") - end - - # Returns the default value from content definition - # - # If the value is a symbol it gets passed through i18n - # inside the +alchemy.default_content_texts+ scope - def default_value(default = definition[:default]) - case default - when Symbol - Alchemy.t(default, scope: :default_content_texts) - else - default - end - end - end -end diff --git a/app/models/alchemy/content/factory.rb b/app/models/alchemy/content/factory.rb deleted file mode 100644 index 6ee14d835a..0000000000 --- a/app/models/alchemy/content/factory.rb +++ /dev/null @@ -1,143 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - # Holds everything concerning the building and creating of contents and the related essence object. - # - class Content < BaseRecord - module Factory - extend ActiveSupport::Concern - - module ClassMethods - SKIPPED_ATTRIBUTES_ON_COPY = %w(position created_at updated_at creator_id updater_id element_id id) - - # Builds a new content as descriped in the elements.yml file. - # - # @param [Hash] - # The content definition used for finding the content in +elements.yml+ file - # - def new(attributes = {}) - element = attributes[:element] || Element.find_by(id: attributes[:element_id]) - return super if attributes.empty? || element.nil? - - definition = element.content_definition_for(attributes[:name]) - if definition.blank? && attributes[:essence_type].nil? - raise ContentDefinitionError, "No definition found in elements.yml for #{attributes.inspect} and #{element.inspect}" - end - - super( - name: attributes[:name], - essence_type: attributes[:essence_type] || normalize_essence_type(definition[:type]), - element: element, - ).tap(&:build_essence) - end - - # Creates a new content from elements definition in the +elements.yml+ file. - # - # 1. It builds the content - # 2. It creates the essence record (content object gets saved) - # - # @return [Alchemy::Content] - # - def create(attributes = {}) - new(attributes).tap do |content| - content.essence.save && content.save - end - end - - # Creates a copy of source and also copies the associated essence. - # - # You can pass a differences hash to update the attributes of the copy. - # - # === Example - # - # @copy = Alchemy::Content.copy(@content, {element_id: 3}) - # @copy.element_id # => 3 - # - def copy(source, differences = {}) - Content.new( - source.attributes.with_indifferent_access. - except(*SKIPPED_ATTRIBUTES_ON_COPY). - merge(differences.with_indifferent_access) - ).tap do |new_content| - new_content.build_essence( - source.essence.attributes. - except(*SKIPPED_ATTRIBUTES_ON_COPY) - ) - new_content.save - end - end - - # Returns all content definitions from elements.yml - # - def definitions - definitions = Element.definitions.flat_map { |e| e["contents"] } - definitions.compact! - definitions - end - - # Returns a normalized Essence type - # - # Adds Alchemy module name in front of given essence type - # unless there is a Class with the specified name that is an essence. - # - # @param [String] - # the essence type to normalize - # - def normalize_essence_type(essence_type) - essence_type = essence_type.classify - return essence_type if is_an_essence?(essence_type) - - "Alchemy::#{essence_type}" - end - - private - - def is_an_essence?(essence_type) - klass = Module.const_get(essence_type) - klass.is_a?(Class) && klass.new.acts_as_essence? - rescue NameError - false - end - end - - # Instance Methods - - # Returns the definition hash from +elements.yml+ file. - # - def definition - if element.blank? - log_warning "Content with id #{id} is missing its Element." - return {} - end - element.content_definition_for(name) || {} - end - - # Build essence from definition. - # - # If an optional type is passed, this type of essence gets created. - # - def build_essence(attributes = {}) - self.essence = essence_class.new( - { content: self, ingredient: default_value }.merge(attributes) - ) - end - - # Creates essence from definition. - # - # If an optional type is passed, this type of essence gets created. - # - def create_essence!(attrs = {}) - build_essence(attrs).save! - save! - end - - private - - # Returns a class constant from definition's type field or the essence_type column - # - def essence_class - (essence_type || Content.normalize_essence_type(definition["type"])).constantize - end - end - end -end diff --git a/app/models/alchemy/eager_loading.rb b/app/models/alchemy/eager_loading.rb index 5bcc3cd28b..1ba67bbf90 100644 --- a/app/models/alchemy/eager_loading.rb +++ b/app/models/alchemy/eager_loading.rb @@ -28,7 +28,6 @@ def page_includes(version: :public_version) :tags, { ingredients: :related_object, - contents: :essence, }, ], }, diff --git a/app/models/alchemy/element.rb b/app/models/alchemy/element.rb index 280b201e48..a7448c56a3 100644 --- a/app/models/alchemy/element.rb +++ b/app/models/alchemy/element.rb @@ -21,9 +21,7 @@ # require_dependency "alchemy/element/definitions" -require_dependency "alchemy/element/element_contents" require_dependency "alchemy/element/element_ingredients" -require_dependency "alchemy/element/element_essences" require_dependency "alchemy/element/presenters" module Alchemy @@ -38,7 +36,6 @@ class Element < BaseRecord "amount", "autogenerate", "nestable_elements", - "contents", "hint", "ingredients", "taggable", @@ -59,8 +56,6 @@ class Element < BaseRecord stampable stamper_class_name: Alchemy.user_class.name - has_many :contents, dependent: :destroy, inverse_of: :element - before_destroy :delete_all_nested_elements has_many :all_nested_elements, @@ -93,9 +88,7 @@ class Element < BaseRecord validates_presence_of :name, on: :create validates_format_of :name, on: :create, with: NAME_REGEXP - attr_accessor :autogenerate_contents attr_accessor :autogenerate_nested_elements - after_create :create_contents, unless: -> { autogenerate_contents == false } after_create :generate_nested_elements, unless: -> { autogenerate_nested_elements == false } after_update :touch_touchable_pages @@ -116,8 +109,6 @@ class Element < BaseRecord # Concerns include Definitions - include ElementContents - include ElementEssences include ElementIngredients include Presenters @@ -154,7 +145,7 @@ def dom_id_class=(klass) @_dom_id_class = klass end - # This methods does a copy of source and all depending contents and all of their depending essences. + # This methods does a copy of source and all its ingredients. # # == Options # @@ -272,7 +263,7 @@ def deprecated? # Elements are defined in the +config/alchemy/elements.yml+ file # # - name: article - # contents: + # ingredients: # ... # # == Override the view diff --git a/app/models/alchemy/element/element_contents.rb b/app/models/alchemy/element/element_contents.rb deleted file mode 100644 index e13f3f98b0..0000000000 --- a/app/models/alchemy/element/element_contents.rb +++ /dev/null @@ -1,126 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class Element < BaseRecord - # Methods concerning contents for elements - # - module ElementContents - # Find first content from element by given name. - def content_by_name(name) - contents_by_name(name).first - end - - # Find first content from element by given essence type. - def content_by_type(essence_type) - contents_by_type(essence_type).first - end - - # All contents from element by given name. - def contents_by_name(name) - contents.select { |content| content.name == name.to_s } - end - - alias_method :all_contents_by_name, :contents_by_name - - # All contents from element by given essence type. - def contents_by_type(essence_type) - contents.select do |content| - content.essence_type == Content.normalize_essence_type(essence_type) - end - end - - alias_method :all_contents_by_type, :contents_by_type - - # Updates all related contents by calling +update_essence+ on each of them. - # - # @param contents_attributes [Hash] - # Hash of contents attributes. - # The keys has to be the #id of the content to update. - # The values a Hash of attribute names and values - # - # @return [Boolean] - # True if +errors+ are blank or +contents_attributes+ hash is nil - # - # == Example - # - # @element.update_contents( - # "1" => {ingredient: "Title"}, - # "2" => {link: "https://google.com"} - # ) - # - def update_contents(contents_attributes) - return true if contents_attributes.nil? - - contents.each do |content| - content_hash = contents_attributes[content.id.to_s] || next - content.update_essence(content_hash) || errors.add(:base, :essence_validation_failed) - end - errors.blank? - end - - # Copy current content's contents to given target element - def copy_contents_to(element) - contents.map do |content| - Content.copy(content, element_id: element.id) - end - end - - # Returns the array with the hashes for all element contents in the elements.yml file - def content_definitions - return nil if definition.blank? - - definition["contents"] - end - - # Returns the definition for given content_name - def content_definition_for(content_name) - if content_definitions.blank? - log_warning "Element #{name} is missing the content definition for #{content_name}" - nil - else - content_definitions.detect { |d| d["name"] == content_name.to_s } - end - end - - # Returns an array of all EssenceRichtext contents ids from elements - # - # This is used to re-initialize the TinyMCE editor in the element editor. - # - def richtext_contents_ids - # This is not very efficient SQL wise I know, but we need to iterate - # recursivly through all descendent elements and I don't know how to do this - # in pure SQL. Anyone with a better idea is welcome to submit a patch. - ids = contents.select(&:has_tinymce?).collect(&:id) - expanded_nested_elements = nested_elements.expanded - if expanded_nested_elements.present? - ids += expanded_nested_elements.collect(&:richtext_contents_ids) - end - ids.flatten - end - - # True, if any of the element's contents has essence validations defined. - def has_validations? - !contents.detect(&:has_validations?).blank? - end - - # All element contents where the essence validation has failed. - def contents_with_errors - contents.select(&:essence_validation_failed?) - end - - private - - # creates the contents for this element as described in the elements.yml - # - # If ingredients are defined as well no contents get created, - # ingredients get created instead. - def create_contents - return if definition.fetch(:ingredients, []).any? - - definition.fetch("contents", []).each do |attributes| - Content.create(attributes.merge(element: self)) - end - end - end - end -end diff --git a/app/models/alchemy/element/element_essences.rb b/app/models/alchemy/element/element_essences.rb deleted file mode 100644 index 56b5b1fd4d..0000000000 --- a/app/models/alchemy/element/element_essences.rb +++ /dev/null @@ -1,125 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class Element < BaseRecord - module ElementEssences - # Returns the contents essence value (aka. ingredient) for passed content name. - def ingredient(name) - ing = ingredient_by_role(name) - if ing - Alchemy::Deprecation.warn <<~WARN - Using `element.ingredient` to get the value of an ingredient is deprecated and will change in Alchemy 6.1 - If you want to read the value of an elements ingredient please use `element.value_for(:ingredient_role)` instead. - The next version of Alchemy will return a `Alchemy::Ingredient` record instead. - WARN - ing.value - else - content = content_by_name(name) - return nil if content.blank? - - content.ingredient - end - end - - # True if the element has a content for given name, - # that has an essence value (aka. ingredient) that is not blank. - def has_ingredient?(name) - ingredient(name).present? - end - deprecate has_ingredient?: :has_value_for?, deprecator: Alchemy::Deprecation - - # Returns all essence errors in the format of: - # - # { - # content.name => [ - # error_message_for_validation_1, - # error_message_for_validation_2 - # ] - # } - # - # Get translated error messages with +Element#essence_error_messages+ - # - def essence_errors - essence_errors = {} - contents.each do |content| - if content.essence_validation_failed? - essence_errors[content.name] = content.essence.validation_errors - end - end - essence_errors - end - - # Essence validation errors - # - # == Error messages are translated via I18n - # - # Inside your translation file add translations like: - # - # alchemy: - # content_validations: - # name_of_the_element: - # name_of_the_content: - # validation_error_type: Error Message - # - # NOTE: +validation_error_type+ has to be one of: - # - # * blank - # * taken - # * invalid - # - # === Example: - # - # de: - # alchemy: - # content_validations: - # contactform: - # email: - # invalid: 'Die Email hat nicht das richtige Format' - # - # - # == Error message translation fallbacks - # - # In order to not translate every single content for every element - # you can provide default error messages per content name: - # - # === Example - # - # en: - # alchemy: - # content_validations: - # fields: - # email: - # invalid: E-Mail has wrong format - # blank: E-Mail can't be blank - # - # And even further you can provide general field agnostic error messages: - # - # === Example - # - # en: - # alchemy: - # content_validations: - # errors: - # invalid: %{field} has wrong format - # blank: %{field} can't be blank - # - def essence_error_messages - messages = [] - essence_errors.each do |content_name, errors| - errors.each do |error| - messages << Alchemy.t( - "#{name}.#{content_name}.#{error}", - scope: "content_validations", - default: [ - "fields.#{content_name}.#{error}".to_sym, - "errors.#{error}".to_sym, - ], - field: Content.translated_label_for(content_name, name), - ) - end - end - messages - end - end - end -end diff --git a/app/models/alchemy/element/presenters.rb b/app/models/alchemy/element/presenters.rb index ebc23c6935..cd2f06d902 100644 --- a/app/models/alchemy/element/presenters.rb +++ b/app/models/alchemy/element/presenters.rb @@ -38,16 +38,15 @@ def display_name # Returns a preview text for element. # - # It's taken from the first Content found in the +elements.yml+ definition file. + # It's taken from the first Ingredient found in the +elements.yml+ definition file. # - # You can flag a Content as +as_element_title+ to take this as preview. + # You can flag a Ingredient as +as_element_title+ to take this as preview. # # @param maxlength [Fixnum] (60) # Length of characters after the text will be cut off. # def preview_text(maxlength = 60) preview_text_from_preview_ingredient(maxlength) || - preview_text_from_preview_content(maxlength) || preview_text_from_nested_elements(maxlength) end @@ -85,17 +84,6 @@ def dom_id self.class.dom_id_class.new(self).call end - # The content that's used for element's preview text. - # - # It tries to find one of element's contents that is defined +as_element_title+. - # Takes element's first content if no content is defined +as_element_title+. - # - # @return (Alchemy::Content) - # - def preview_content - @_preview_content ||= contents.detect(&:preview_content?) || contents.first - end - # The ingredient that's used for element's preview text. # # It tries to find one of element's ingredients that is defined +as_element_title+. @@ -115,10 +103,6 @@ def preview_text_from_nested_elements(maxlength) all_nested_elements.first.preview_text(maxlength) end - def preview_text_from_preview_content(maxlength) - preview_content.try!(:preview_text, maxlength) - end - def preview_text_from_preview_ingredient(maxlength) preview_ingredient&.preview_text(maxlength) end diff --git a/app/models/alchemy/essence_audio.rb b/app/models/alchemy/essence_audio.rb deleted file mode 100644 index 92f5d1bd21..0000000000 --- a/app/models/alchemy/essence_audio.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - # @deprecated - class EssenceAudio < ActiveRecord::Base - acts_as_essence( - ingredient_column: :attachment, - preview_text_method: :name, - ) - - belongs_to :attachment, optional: true - end -end diff --git a/app/models/alchemy/essence_boolean.rb b/app/models/alchemy/essence_boolean.rb deleted file mode 100644 index 3c1561ba4d..0000000000 --- a/app/models/alchemy/essence_boolean.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -# == Schema Information -# -# Table name: alchemy_essence_booleans -# -# id :integer not null, primary key -# value :boolean -# created_at :datetime not null -# updated_at :datetime not null -# - -# Stores boolean values. -# Provides a checkbox in the editor views. -module Alchemy - # @deprecated - class EssenceBoolean < BaseRecord - acts_as_essence ingredient_column: "value" - end -end diff --git a/app/models/alchemy/essence_date.rb b/app/models/alchemy/essence_date.rb deleted file mode 100644 index 5e2d6c47eb..0000000000 --- a/app/models/alchemy/essence_date.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -# == Schema Information -# -# Table name: alchemy_essence_dates -# -# id :integer not null, primary key -# date :datetime -# created_at :datetime not null -# updated_at :datetime not null -# - -module Alchemy - # @deprecated - class EssenceDate < BaseRecord - acts_as_essence ingredient_column: "date" - - # Returns self.date for the Element#preview_text method. - def preview_text(_maxlength = nil) - return "" if date.blank? - - ::I18n.l(date, format: :'alchemy.essence_date') - end - end -end diff --git a/app/models/alchemy/essence_file.rb b/app/models/alchemy/essence_file.rb deleted file mode 100644 index 585bedafc1..0000000000 --- a/app/models/alchemy/essence_file.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -# == Schema Information -# -# Table name: alchemy_essence_files -# -# id :integer not null, primary key -# attachment_id :integer -# title :string -# css_class :string -# created_at :datetime not null -# updated_at :datetime not null -# link_text :string -# - -module Alchemy - # @deprecated - class EssenceFile < BaseRecord - belongs_to :attachment, optional: true - acts_as_essence ingredient_column: "attachment" - - def attachment_url - return if attachment.nil? - - routes.download_attachment_path( - id: attachment.id, - name: attachment.slug, - format: attachment.suffix, - ) - end - - def preview_text(max = 30) - return "" if attachment.blank? - - attachment.name.to_s[0..max - 1] - end - - # Returns a serialized ingredient value for json api - def serialized_ingredient - attachment_url - end - - private - - def routes - @routes ||= Engine.routes.url_helpers - end - end -end diff --git a/app/models/alchemy/essence_headline.rb b/app/models/alchemy/essence_headline.rb deleted file mode 100644 index adf820c1ca..0000000000 --- a/app/models/alchemy/essence_headline.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - # @deprecated - class EssenceHeadline < BaseRecord - acts_as_essence - - after_initialize :set_level_and_size - - def preview_text(maxlength = 30) - "H#{level}: #{body}"[0..maxlength - 1] - end - - def level_options - levels.map { |level| ["H#{level}", level] } - end - - def size_options - sizes.map { |size| ["H#{size}", size] } - end - - private - - def content_settings - content&.settings || {} - end - - def levels - content_settings.fetch(:levels, (1..6)) - end - - def sizes - content_settings.fetch(:sizes, []) - end - - def set_level_and_size - self.level ||= levels.first - self.size ||= sizes.first - end - end -end diff --git a/app/models/alchemy/essence_html.rb b/app/models/alchemy/essence_html.rb deleted file mode 100644 index 247316b2b0..0000000000 --- a/app/models/alchemy/essence_html.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -# == Schema Information -# -# Table name: alchemy_essence_htmls -# -# id :integer not null, primary key -# source :text -# created_at :datetime not null -# updated_at :datetime not null -# - -module Alchemy - # @deprecated - class EssenceHtml < BaseRecord - acts_as_essence ingredient_column: "source" - - # Returns the first x (default = 30) (HTML escaped) characters from self.source for the Element#preview_text method. - def preview_text(maxlength = 30) - ::CGI.escapeHTML(source.to_s)[0..maxlength] - end - end -end diff --git a/app/models/alchemy/essence_link.rb b/app/models/alchemy/essence_link.rb deleted file mode 100644 index 0fae58e5a2..0000000000 --- a/app/models/alchemy/essence_link.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -# == Schema Information -# -# Table name: alchemy_essence_links -# -# id :integer not null, primary key -# link :string -# link_title :string -# link_target :string -# link_class_name :string -# created_at :datetime not null -# updated_at :datetime not null -# - -module Alchemy - # @deprecated - class EssenceLink < BaseRecord - acts_as_essence ingredient_column: "link" - end -end diff --git a/app/models/alchemy/essence_node.rb b/app/models/alchemy/essence_node.rb deleted file mode 100644 index 8ed1972f0c..0000000000 --- a/app/models/alchemy/essence_node.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - # @deprecated - class EssenceNode < BaseRecord - acts_as_essence( - ingredient_column: :node, - preview_text_column: :node_name, - belongs_to: { - class_name: "Alchemy::Node", - foreign_key: :node_id, - inverse_of: :essence_nodes, - optional: true, - }, - ) - - delegate :name, to: :node, prefix: true, allow_nil: true - end -end diff --git a/app/models/alchemy/essence_page.rb b/app/models/alchemy/essence_page.rb deleted file mode 100644 index cff72a51e0..0000000000 --- a/app/models/alchemy/essence_page.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - # @deprecated - class EssencePage < BaseRecord - acts_as_essence( - ingredient_column: :page, - preview_text_method: :name, - belongs_to: { - class_name: "Alchemy::Page", - foreign_key: :page_id, - inverse_of: :essence_pages, - optional: true, - }, - ) - end -end diff --git a/app/models/alchemy/essence_picture.rb b/app/models/alchemy/essence_picture.rb deleted file mode 100644 index 20b7dcfb00..0000000000 --- a/app/models/alchemy/essence_picture.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -# == Schema Information -# -# Table name: alchemy_essence_pictures -# -# id :integer not null, primary key -# picture_id :integer -# caption :string -# title :string -# alt_tag :string -# link :string -# link_class_name :string -# link_title :string -# css_class :string -# link_target :string -# created_at :datetime not null -# updated_at :datetime not null -# crop_from :string -# crop_size :string -# render_size :string -# - -module Alchemy - # @deprecated - class EssencePicture < BaseRecord - include Alchemy::PictureThumbnails - - acts_as_essence ingredient_column: :picture, belongs_to: { - class_name: "Alchemy::Picture", - foreign_key: :picture_id, - inverse_of: :essence_pictures, - optional: true, - } - - delegate :settings, to: :content - - before_save :replace_newlines - - # The name of the picture used as preview text in element editor views. - # - # @param max [Integer] - # The maximum length of the text returned. - # - # @return [String] - def preview_text(max = 30) - return "" if picture.nil? - - picture.name.to_s[0..max - 1] - end - - # Returns a serialized ingredient value for json api - # - # @return [String] - def serialized_ingredient - picture_url(content.settings) - end - - private - - def replace_newlines - return nil if caption.nil? - - caption.gsub!(/(\r\n|\r|\n)/, "
") - end - end -end diff --git a/app/models/alchemy/essence_picture_view.rb b/app/models/alchemy/essence_picture_view.rb deleted file mode 100644 index c4180c0e0b..0000000000 --- a/app/models/alchemy/essence_picture_view.rb +++ /dev/null @@ -1,90 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - # Renders an essence picture view - # @deprecated - class EssencePictureView - include ActionView::Helpers::AssetTagHelper - include ActionView::Helpers::UrlHelper - include Rails.application.routes.url_helpers - - attr_reader :content, :essence, :html_options, :options, :picture - - DEFAULT_OPTIONS = { - show_caption: true, - disable_link: false, - srcset: [], - sizes: [], - }.with_indifferent_access - - def initialize(content, options = {}, html_options = {}) - @content = content - @options = DEFAULT_OPTIONS.merge(content.settings).merge(options) - @html_options = html_options - @essence = content.essence - @picture = essence.picture - end - - def render - return if picture.blank? - - output = caption ? img_tag + caption : img_tag - - if is_linked? - output = link_to(output, url_for(essence.link), { - title: essence.link_title.presence, - target: essence.link_target == "blank" ? "_blank" : nil, - data: { link_target: essence.link_target.presence }, - }) - end - - if caption - content_tag(:figure, output, { class: essence.css_class.presence }.merge(html_options)) - else - output - end - end - - def caption - return unless show_caption? - - @_caption ||= content_tag(:figcaption, essence.caption) - end - - def src - essence.picture_url(options.except(*DEFAULT_OPTIONS.keys)) - end - - def img_tag - @_img_tag ||= image_tag( - src, { - alt: alt_text, - title: essence.title.presence, - class: caption ? nil : essence.css_class.presence, - srcset: srcset.join(", ").presence, - sizes: options[:sizes].join(", ").presence, - }.merge(caption ? {} : html_options) - ) - end - - def show_caption? - options[:show_caption] && essence.caption.present? - end - - def is_linked? - !options[:disable_link] && essence.link.present? - end - - def srcset - options[:srcset].map do |size| - url = essence.picture_url(size: size) - width, height = size.split("x") - width.present? ? "#{url} #{width}w" : "#{url} #{height}h" - end - end - - def alt_text - essence.alt_tag.presence || html_options.delete(:alt) || essence.picture.name&.humanize - end - end -end diff --git a/app/models/alchemy/essence_richtext.rb b/app/models/alchemy/essence_richtext.rb deleted file mode 100644 index 872e413fbb..0000000000 --- a/app/models/alchemy/essence_richtext.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -# == Schema Information -# -# Table name: alchemy_essence_richtexts -# -# id :integer not null, primary key -# body :text -# stripped_body :text -# public :boolean -# created_at :datetime not null -# updated_at :datetime not null -# - -module Alchemy - # @deprecated - class EssenceRichtext < BaseRecord - acts_as_essence preview_text_column: "stripped_body" - - before_save :strip_content - before_save :sanitize_content - - def has_tinymce? - true - end - - private - - def strip_content - self.stripped_body = Rails::Html::FullSanitizer.new.sanitize(body) - end - - def sanitize_content - self.sanitized_body = Rails::Html::SafeListSanitizer.new.sanitize( - body, - content_sanitizer_settings - ) - end - - def content_sanitizer_settings - content&.settings&.fetch(:sanitizer, {}) || {} - end - end -end diff --git a/app/models/alchemy/essence_select.rb b/app/models/alchemy/essence_select.rb deleted file mode 100644 index d40de76542..0000000000 --- a/app/models/alchemy/essence_select.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -# == Schema Information -# -# Table name: alchemy_essence_selects -# -# id :integer not null, primary key -# value :string -# created_at :datetime not null -# updated_at :datetime not null -# - -# Provides a select box that stores string values. -module Alchemy - # @deprecated - class EssenceSelect < BaseRecord - acts_as_essence ingredient_column: "value" - end -end diff --git a/app/models/alchemy/essence_text.rb b/app/models/alchemy/essence_text.rb deleted file mode 100644 index 4965ba537d..0000000000 --- a/app/models/alchemy/essence_text.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -# == Schema Information -# -# Table name: alchemy_essence_texts -# -# id :integer not null, primary key -# body :text -# link :string -# link_title :string -# link_class_name :string -# public :boolean default(FALSE) -# link_target :string -# created_at :datetime not null -# updated_at :datetime not null -# - -module Alchemy - # @deprecated - class EssenceText < BaseRecord - acts_as_essence - end -end diff --git a/app/models/alchemy/essence_video.rb b/app/models/alchemy/essence_video.rb deleted file mode 100644 index c9bc58bd91..0000000000 --- a/app/models/alchemy/essence_video.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - # @deprecated - class EssenceVideo < ActiveRecord::Base - acts_as_essence( - ingredient_column: :attachment, - preview_text_method: :name, - ) - - belongs_to :attachment, optional: true - end -end diff --git a/app/models/alchemy/ingredient.rb b/app/models/alchemy/ingredient.rb index dfea2eb3f6..5f47c723af 100644 --- a/app/models/alchemy/ingredient.rb +++ b/app/models/alchemy/ingredient.rb @@ -13,6 +13,8 @@ class DefinitionError < StandardError; end belongs_to :element, touch: true, class_name: "Alchemy::Element", inverse_of: :ingredients belongs_to :related_object, polymorphic: true, optional: true + has_one :page, through: :element, class_name: "Alchemy::Page" + after_initialize :set_default_value, if: -> { definition.key?(:default) && value.nil? } diff --git a/app/models/alchemy/node.rb b/app/models/alchemy/node.rb index 3bb20a20ae..c8b29d166e 100644 --- a/app/models/alchemy/node.rb +++ b/app/models/alchemy/node.rb @@ -4,7 +4,7 @@ module Alchemy class Node < BaseRecord VALID_URL_REGEX = /\A(\/|\D[a-z\+\d\.\-]+:)/ - before_destroy :check_if_related_essence_nodes_present + before_destroy :check_if_related_node_ingredients_present acts_as_nested_set scope: "language_id", touch: true stampable stamper_class_name: Alchemy.user_class.name @@ -14,7 +14,10 @@ class Node < BaseRecord has_one :site, through: :language - has_many :essence_nodes, class_name: "Alchemy::EssenceNode", foreign_key: :node_id, inverse_of: :ingredient_association + has_many :node_ingredients, + class_name: "Alchemy::Ingredients::Node", + foreign_key: :related_object_id, + inverse_of: :related_object before_validation :translate_root_menu_name, if: -> { root? } before_validation :set_menu_type_from_root, unless: -> { root? } @@ -76,10 +79,10 @@ def to_partial_path private - def check_if_related_essence_nodes_present - dependent_essence_nodes = self_and_descendants.flat_map(&:essence_nodes) - if dependent_essence_nodes.any? - errors.add(:base, :essence_nodes_present, page_names: dependent_essence_nodes.map(&:page).map(&:name).to_sentence) + def check_if_related_node_ingredients_present + dependent_node_ingredients = self_and_descendants.flat_map(&:node_ingredients) + if dependent_node_ingredients.any? + errors.add(:base, :node_ingredients_present, page_names: dependent_node_ingredients.map { |i| i.element&.page&.name }.to_sentence) throw(:abort) end end diff --git a/app/models/alchemy/page/page_elements.rb b/app/models/alchemy/page/page_elements.rb index e799069a7c..8a86fcaafb 100644 --- a/app/models/alchemy/page/page_elements.rb +++ b/app/models/alchemy/page/page_elements.rb @@ -19,7 +19,7 @@ module PageElements has_many :fixed_elements, -> { fixed.published } end - has_many :contents, through: :elements + has_many :ingredients, through: :elements has_and_belongs_to_many :to_be_swept_elements, -> { distinct }, class_name: "Alchemy::Element", join_table: ElementToPage.table_name @@ -58,17 +58,17 @@ def copy_elements(source, target) # # - name: headline # unique: true - # contents: + # ingredients: # - name: headline - # type: EssenceText + # type: Text # # == Example of limited element: # # - name: article # amount: 2 - # contents: + # ingredients: # - name: text - # type: EssenceRichtext + # type: Richtext # def available_element_definitions(only_element_named = nil) @_element_definitions ||= if only_element_named @@ -156,15 +156,6 @@ def element_definitions_by_name(names) end end - # Returns an array of all EssenceRichtext contents ids from not folded elements - # - def richtext_contents_ids - Alchemy::Content.joins(:element) - .where(Element.table_name => { page_version_id: draft_version.id, folded: false }) - .select(&:has_tinymce?) - .collect(&:id) - end - # Returns an array of all Richtext ingredients ids from not folded elements # def richtext_ingredients_ids diff --git a/app/models/alchemy/picture.rb b/app/models/alchemy/picture.rb index da7dc7adf3..8678552e92 100644 --- a/app/models/alchemy/picture.rb +++ b/app/models/alchemy/picture.rb @@ -47,13 +47,12 @@ class Picture < BaseRecord include Alchemy::TouchElements include Calculations - has_many :essence_pictures, - class_name: "Alchemy::EssencePicture", - foreign_key: "picture_id", - inverse_of: :ingredient_association + has_many :picture_ingredients, + class_name: "Alchemy::Ingredients::Picture", + foreign_key: "related_object_id", + inverse_of: :related_object - has_many :contents, through: :essence_pictures - has_many :elements, through: :contents + has_many :elements, through: :picture_ingredients has_many :pages, through: :elements has_many :thumbs, class_name: "Alchemy::PictureThumb", dependent: :destroy @@ -282,7 +281,7 @@ def restricted? # Returns true if picture is not assigned to any EssencePicture. # def deletable? - essence_pictures.empty? + picture_ingredients.empty? end # A size String from original image file values. diff --git a/app/serializers/alchemy/content_serializer.rb b/app/serializers/alchemy/content_serializer.rb deleted file mode 100644 index 1adc3b6e98..0000000000 --- a/app/serializers/alchemy/content_serializer.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class ContentSerializer < ActiveModel::Serializer - attributes :id, - :name, - :ingredient, - :element_id, - :settings - - has_one :essence, polymorphic: true - - def ingredient - object.serialized_ingredient - end - end -end diff --git a/app/serializers/alchemy/element_serializer.rb b/app/serializers/alchemy/element_serializer.rb index cd75229add..59782ab9d9 100644 --- a/app/serializers/alchemy/element_serializer.rb +++ b/app/serializers/alchemy/element_serializer.rb @@ -10,16 +10,11 @@ class ElementSerializer < ActiveModel::Serializer :tag_list, :created_at, :updated_at, - :ingredients, - :content_ids, :dom_id, :display_name has_many :nested_elements - - def ingredients - object.contents.collect(&:serialize) - end + has_many :ingredients def display_name object.display_name_with_preview_text diff --git a/app/serializers/alchemy/essence_boolean_serializer.rb b/app/serializers/alchemy/essence_boolean_serializer.rb deleted file mode 100644 index 6b790875df..0000000000 --- a/app/serializers/alchemy/essence_boolean_serializer.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class EssenceBooleanSerializer < ActiveModel::Serializer - attributes( - :id, - :value, - ) - end -end diff --git a/app/serializers/alchemy/essence_date_serializer.rb b/app/serializers/alchemy/essence_date_serializer.rb deleted file mode 100644 index b738f6a4e7..0000000000 --- a/app/serializers/alchemy/essence_date_serializer.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class EssenceDateSerializer < ActiveModel::Serializer - attributes( - :id, - :date, - ) - end -end diff --git a/app/serializers/alchemy/essence_file_serializer.rb b/app/serializers/alchemy/essence_file_serializer.rb deleted file mode 100644 index 7ccb46ea7a..0000000000 --- a/app/serializers/alchemy/essence_file_serializer.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class EssenceFileSerializer < ActiveModel::Serializer - attributes( - :id, - :title, - :css_class, - ) - - has_one :attachment - end -end diff --git a/app/serializers/alchemy/essence_html_serializer.rb b/app/serializers/alchemy/essence_html_serializer.rb deleted file mode 100644 index 8f76946360..0000000000 --- a/app/serializers/alchemy/essence_html_serializer.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class EssenceHtmlSerializer < ActiveModel::Serializer - attributes( - :id, - :source, - ) - end -end diff --git a/app/serializers/alchemy/essence_link_serializer.rb b/app/serializers/alchemy/essence_link_serializer.rb deleted file mode 100644 index 29dcec97dd..0000000000 --- a/app/serializers/alchemy/essence_link_serializer.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class EssenceLinkSerializer < ActiveModel::Serializer - attributes( - :id, - :link, - :link_title, - :link_target, - :link_class_name, - ) - end -end diff --git a/app/serializers/alchemy/essence_picture_serializer.rb b/app/serializers/alchemy/essence_picture_serializer.rb deleted file mode 100644 index 5ae7a34c22..0000000000 --- a/app/serializers/alchemy/essence_picture_serializer.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class EssencePictureSerializer < ActiveModel::Serializer - attributes( - :id, - :picture_id, - :caption, - :title, - :alt_tag, - :css_class, - :link, - ) - - has_one :picture - - def link - return if object.link.blank? - - { - url: object.link, - css_class: object.link_class_name, - title: object.link_title, - target: object.link_target, - } - end - end -end diff --git a/app/serializers/alchemy/essence_richtext_serializer.rb b/app/serializers/alchemy/essence_richtext_serializer.rb deleted file mode 100644 index bd8291748f..0000000000 --- a/app/serializers/alchemy/essence_richtext_serializer.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class EssenceRichtextSerializer < ActiveModel::Serializer - attributes( - :id, - :body, - :stripped_body, - ) - end -end diff --git a/app/serializers/alchemy/essence_select_serializer.rb b/app/serializers/alchemy/essence_select_serializer.rb deleted file mode 100644 index 51d9a1a731..0000000000 --- a/app/serializers/alchemy/essence_select_serializer.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class EssenceSelectSerializer < ActiveModel::Serializer - attributes( - :id, - :value, - ) - end -end diff --git a/app/serializers/alchemy/essence_text_serializer.rb b/app/serializers/alchemy/essence_text_serializer.rb deleted file mode 100644 index dd2326518c..0000000000 --- a/app/serializers/alchemy/essence_text_serializer.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -module Alchemy - class EssenceTextSerializer < ActiveModel::Serializer - attributes( - :id, - :body, - :link, - ) - - def link - return if object.link.blank? - - { - url: object.link, - title: object.link_title, - css_class: object.link_class_name, - target: object.link_target, - } - end - end -end diff --git a/app/services/alchemy/delete_elements.rb b/app/services/alchemy/delete_elements.rb index a3b7c821f1..a5df3159c0 100644 --- a/app/services/alchemy/delete_elements.rb +++ b/app/services/alchemy/delete_elements.rb @@ -3,6 +3,7 @@ module Alchemy class DeleteElements class WouldLeaveOrphansError < StandardError; end + attr_reader :elements def initialize(elements) @@ -14,13 +15,6 @@ def call raise WouldLeaveOrphansError end - contents = Alchemy::Content.where(element_id: elements.map(&:id)) - contents.group_by(&:essence_type) - .transform_values! { |value| value.map(&:essence_id) } - .each do |class_name, ids| - class_name.constantize.where(id: ids).delete_all - end - contents.delete_all Gutentag::Tagging.where(taggable: elements).delete_all delete_elements end diff --git a/app/services/alchemy/duplicate_element.rb b/app/services/alchemy/duplicate_element.rb index 461f92ea02..89b57660cb 100644 --- a/app/services/alchemy/duplicate_element.rb +++ b/app/services/alchemy/duplicate_element.rb @@ -25,7 +25,6 @@ def call(differences = {}) .except(*SKIPPED_ATTRIBUTES_ON_COPY) .merge(differences) .merge( - autogenerate_contents: false, autogenerate_ingredients: false, autogenerate_nested_elements: false, tags: source_element.tags, @@ -35,17 +34,13 @@ def call(differences = {}) new_element.ingredients = source_element.ingredients.map(&:dup) new_element.save! - source_element.contents.map do |content| - Content.copy(content, element: new_element) - end - nested_elements = repository.children_of(source_element) Element.acts_as_list_no_update do nested_elements.each.with_index(1) do |nested_element, position| self.class.new(nested_element, repository: repository).call( parent_element: new_element, page_version: new_element.page_version, - position: position + position: position, ) end end diff --git a/app/views/alchemy/admin/contents/create.js.erb b/app/views/alchemy/admin/contents/create.js.erb deleted file mode 100644 index b99a1e4a82..0000000000 --- a/app/views/alchemy/admin/contents/create.js.erb +++ /dev/null @@ -1,21 +0,0 @@ -var editor_html = '<%= j render(Alchemy::ContentEditor.new(@content)) %>'; - -$("[data-element-<%= @content.element_id %>-missing-content=\"<%= @content.name %>\"]").replaceWith(editor_html); - -<% if @content.essence_type == "Alchemy::EssencePicture" && @content.ingredient %> - -$('#picture_to_assign_<%= @content.ingredient.id %> a').attr('href', '#').off('click'); - -<% elsif @content.essence_type == "Alchemy::EssenceDate" %> - -Alchemy.Datepicker('#element_<%= @content.element_id %>'); - -<% elsif @content.essence_type == "Alchemy::EssenceRichtext" %> - -Alchemy.Tinymce.initEditor(<%= @content.id %>); - -<% end %> - -Alchemy.reloadPreview(); -Alchemy.closeCurrentDialog(); -Alchemy.SelectBox("#element_<%= @content.element_id %>"); diff --git a/app/views/alchemy/admin/elements/_element.html.erb b/app/views/alchemy/admin/elements/_element.html.erb index f4bbb7df4d..a7b7f254b0 100644 --- a/app/views/alchemy/admin/elements/_element.html.erb +++ b/app/views/alchemy/admin/elements/_element.html.erb @@ -20,7 +20,7 @@ <% if element.editable? %> <%= form_for [alchemy, :admin, element], remote: true, - html: {id: "element_#{element.id}_form".html_safe, class: 'element-content'} do |f| %> + html: {id: "element_#{element.id}_form".html_safe, class: 'element-body'} do |f| %>
@@ -31,35 +31,18 @@ <% element.ingredients.select { |i| i.definition[:group] }.group_by { |i| i.definition[:group] }.each do |group, ingredients| %> -
- <%= link_to '#', id: "element_#{element.id}_content_group_#{group.parameterize.underscore}_header", class: 'content-group-header', data: { toggle_content_group: true } do %> +
+ <%= link_to '#', id: "element_#{element.id}_ingredient_group_#{group.parameterize.underscore}_header", class: 'ingredient-group-header', data: { toggle_ingredient_group: true } do %> <%= element.translated_group group %> - + <% end %> - <%= content_tag :div, id: "element_#{element.id}_content_group_#{group.parameterize.underscore}", class: 'content-group-contents' do %> + <%= content_tag :div, id: "element_#{element.id}_ingredient_group_#{group.parameterize.underscore}", class: 'ingredient-group-ingredients' do %> <%= render ingredients, element_form: f %> <% end %>
<% end %>
<% end %> - -
- <%= render element.contents.select { |c| !c.definition[:group] } %> - - - <% element.contents.select { |c| c.definition[:group] }.group_by { |c| c.definition[:group] }.each do |group, contents| %> -
- <%= link_to '#', id: "element_#{element.id}_content_group_#{group.parameterize.underscore}_header", class: 'content-group-header', data: { toggle_content_group: true } do %> - <%= element.translated_group group %> - - <% end %> - <%= content_tag :div, id: "element_#{element.id}_content_group_#{group.parameterize.underscore}", class: 'content-group-contents' do %> - <%= render contents, element_form: f %> - <% end %> -
- <% end %> -
<% if element.taggable? %>
diff --git a/app/views/alchemy/admin/elements/create.js.erb b/app/views/alchemy/admin/elements/create.js.erb index 7db8a22d64..b95c7979b1 100644 --- a/app/views/alchemy/admin/elements/create.js.erb +++ b/app/views/alchemy/admin/elements/create.js.erb @@ -34,7 +34,7 @@ Alchemy.growl('<%= Alchemy.t(:successfully_added_element) %>'); Alchemy.closeCurrentDialog(); - Alchemy.Tinymce.init(<%= (@element.richtext_contents_ids + @element.richtext_ingredients_ids).to_json %>); + Alchemy.Tinymce.init(<%= @element.richtext_ingredients_ids.to_json %>); Alchemy.PreviewWindow.refresh(function() { Alchemy.ElementEditors.focusElementPreview(<%= @element.id %>); }); diff --git a/app/views/alchemy/admin/elements/fold.js.erb b/app/views/alchemy/admin/elements/fold.js.erb index 4fc1ac473e..44ca3082a5 100644 --- a/app/views/alchemy/admin/elements/fold.js.erb +++ b/app/views/alchemy/admin/elements/fold.js.erb @@ -14,12 +14,12 @@ <% if @element.folded? -%> - Alchemy.Tinymce.remove(<%= (@element.richtext_contents_ids + @element.richtext_ingredients_ids).to_json %>); + Alchemy.Tinymce.remove(<%= @element.richtext_ingredients_ids.to_json %>); <% else -%> $el.trigger('FocusElementEditor.Alchemy'); - Alchemy.Tinymce.init(<%= (@element.richtext_contents_ids + @element.richtext_ingredients_ids).to_json %>); + Alchemy.Tinymce.init(<%= @element.richtext_ingredients_ids.to_json %>); Alchemy.GUI.initElement($el); Alchemy.SortableElements( <%= @page.id %>, diff --git a/app/views/alchemy/admin/elements/update.js.erb b/app/views/alchemy/admin/elements/update.js.erb index f44af7365e..7c4c4b670b 100644 --- a/app/views/alchemy/admin/elements/update.js.erb +++ b/app/views/alchemy/admin/elements/update.js.erb @@ -1,7 +1,7 @@ (function() { var $el = $('#element_<%= @element.id %>'); var $errors = $('#element_<%= @element.id %>_errors'); - $('> .element-content .content_editor, > .element-content .ingredient-editor', $el).removeClass('validation_failed'); + $('> .element-body .ingredient-editor', $el).removeClass('validation_failed'); <%- if @element_validated -%> @@ -20,7 +20,6 @@ Alchemy.growl('<%= j @notice %>', 'warn'); $errors.html('<%= j @error_message %>
  • <%== j @error_messages.join("
  • ") %>
'); $errors.show(); - $('<%= @element.contents_with_errors.map { |content| "#" + content.dom_id }.join(", ") %>').addClass('validation_failed'); $('<%== @element.ingredients_with_errors.map { |ingredient| "[data-ingredient-id=\"#{ingredient.id}\"]" }.join(", ") %>').addClass('validation_failed'); Alchemy.Buttons.enable($el); diff --git a/app/views/alchemy/admin/essence_audios/edit.html.erb b/app/views/alchemy/admin/essence_audios/edit.html.erb deleted file mode 100644 index 728c81fe09..0000000000 --- a/app/views/alchemy/admin/essence_audios/edit.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -<%= alchemy_form_for [:admin, @essence_audio] do |f| %> - <%= f.input :autoplay %> - <%= f.input :controls %> - <%= f.input :loop %> - <%= f.input :muted %> - <%= f.submit Alchemy.t(:save) %> -<% end %> diff --git a/app/views/alchemy/admin/essence_files/edit.html.erb b/app/views/alchemy/admin/essence_files/edit.html.erb deleted file mode 100644 index 25fab7e877..0000000000 --- a/app/views/alchemy/admin/essence_files/edit.html.erb +++ /dev/null @@ -1,21 +0,0 @@ -<% css_classes = @content.settings[:css_classes] %> - -<%= alchemy_form_for [:admin, @essence_file] do |f| %> - <%= f.input :link_text %> - <%= f.input :title %> - <%- if css_classes.present? -%> - <%= f.input :css_class, - collection: css_classes, - include_blank: Alchemy.t('None'), - input_html: {class: 'alchemy_selectbox'} %> - <%- else -%> - <%= f.input :css_class, - label: Alchemy.t(:position_in_text), - collection: [ - [Alchemy.t(:above), "no_float"], - [Alchemy.t(:left), "left"], - [Alchemy.t(:right), "right"] - ], include_blank: Alchemy.t('Layout default'), input_html: {class: 'alchemy_selectbox'} %> - <%- end -%> - <%= f.submit Alchemy.t(:save) %> -<% end %> diff --git a/app/views/alchemy/admin/essence_pictures/destroy.js.erb b/app/views/alchemy/admin/essence_pictures/destroy.js.erb deleted file mode 100644 index baa948df4a..0000000000 --- a/app/views/alchemy/admin/essence_pictures/destroy.js.erb +++ /dev/null @@ -1,5 +0,0 @@ -(function() { - $('#essence_picture_<%= @content_id %>').remove(); - Alchemy.reloadPreview(); - Alchemy.pleaseWaitOverlay(false); -})() diff --git a/app/views/alchemy/admin/essence_pictures/edit.html.erb b/app/views/alchemy/admin/essence_pictures/edit.html.erb deleted file mode 100644 index 35ec0dd901..0000000000 --- a/app/views/alchemy/admin/essence_pictures/edit.html.erb +++ /dev/null @@ -1,30 +0,0 @@ -<%= alchemy_form_for @essence_picture, - url: alchemy.admin_essence_picture_path(@essence_picture) do |f| %> - <%= hidden_field_tag 'content_id', @content.id %> - <%= f.input :caption, as: @content.settings[:caption_as_textarea] ? 'text' : 'string' %> - <%= f.input :title %> - <%= f.input :alt_tag %> - <%- if @content.settings[:sizes].present? && @content.settings[:srcset].blank? -%> - <%= f.input :render_size, - collection: [ - [Alchemy.t('Layout default'), ""] - ] + @content.settings[:sizes].to_a, - include_blank: false, - input_html: {class: 'alchemy_selectbox'} %> - <%- end -%> - <%- if @content.settings[:css_classes].present? -%> - <%= f.input :css_class, - collection: @content.settings[:css_classes], - include_blank: Alchemy.t('None'), - input_html: {class: 'alchemy_selectbox'} %> - <%- else -%> - <%= f.input :css_class, - label: Alchemy.t(:position_in_text), - collection: [ - [Alchemy.t(:above), "no_float"], - [Alchemy.t(:left), "left"], - [Alchemy.t(:right), "right"] - ], include_blank: Alchemy.t("Layout default"), input_html: {class: 'alchemy_selectbox'} %> - <%- end -%> - <%= f.submit Alchemy.t(:save) %> -<% end %> diff --git a/app/views/alchemy/admin/essence_pictures/save_link.js.erb b/app/views/alchemy/admin/essence_pictures/save_link.js.erb deleted file mode 100644 index a7fdbc0bf1..0000000000 --- a/app/views/alchemy/admin/essence_pictures/save_link.js.erb +++ /dev/null @@ -1,3 +0,0 @@ -Alchemy.closeCurrentDialog(); -Alchemy.reloadPreview(); -Alchemy.growl('<%= @notice %>'); diff --git a/app/views/alchemy/admin/essence_pictures/update.js.erb b/app/views/alchemy/admin/essence_pictures/update.js.erb deleted file mode 100644 index 47e1680f54..0000000000 --- a/app/views/alchemy/admin/essence_pictures/update.js.erb +++ /dev/null @@ -1,8 +0,0 @@ -(function($) { - Alchemy.closeCurrentDialog(); - Alchemy.setElementDirty('#element_<%= @content.element.id %>'); -<% if @content.ingredient %> - $('.thumbnail_background img', '#<%= @content.dom_id %>').replaceWith('<%= essence_picture_thumbnail(@content) %>'); - Alchemy.ImageLoader('#<%= @content.dom_id %> .thumbnail_background'); -<% end %> -})(jQuery); diff --git a/app/views/alchemy/admin/essence_videos/edit.html.erb b/app/views/alchemy/admin/essence_videos/edit.html.erb deleted file mode 100644 index 5bc5b4fe2b..0000000000 --- a/app/views/alchemy/admin/essence_videos/edit.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -<%= alchemy_form_for [:admin, @essence_video] do |f| %> - <%= f.input :width %> - <%= f.input :height %> - <%= f.input :autoplay %> - <%= f.input :controls %> - <%= f.input :loop %> - <%= f.input :muted %> - <%= f.input :playsinline %> - <%= f.input :preload, collection: %w(auto none metadata), - include_blank: false, input_html: {class: 'alchemy_selectbox'} %> - <%= f.submit Alchemy.t(:save) %> -<% end %> diff --git a/app/views/alchemy/admin/pages/edit.html.erb b/app/views/alchemy/admin/pages/edit.html.erb index b286e85f70..ee4987a5dd 100644 --- a/app/views/alchemy/admin/pages/edit.html.erb +++ b/app/views/alchemy/admin/pages/edit.html.erb @@ -197,7 +197,7 @@ Alchemy.SortableElements(<%= @page.id %>, '<%= form_authenticity_token %>'); Alchemy.ElementEditors.init(); Alchemy.SelectBox('.element-editor'); - Alchemy.Tinymce.init(<%= (@page.richtext_contents_ids + @page.richtext_ingredients_ids).to_json %>); + Alchemy.Tinymce.init(<%= @page.richtext_ingredients_ids.to_json %>); $('#fixed-elements').tabs().tabs('paging', { follow: true, followOnSelect: true, diff --git a/app/views/alchemy/essences/_essence_audio_editor.html.erb b/app/views/alchemy/essences/_essence_audio_editor.html.erb deleted file mode 100644 index 08ff6b84ae..0000000000 --- a/app/views/alchemy/essences/_essence_audio_editor.html.erb +++ /dev/null @@ -1,4 +0,0 @@ -<%= render( - "alchemy/essences/essence_file_editor", - essence_file_editor: essence_audio_editor -) %> diff --git a/app/views/alchemy/essences/_essence_audio_view.html.erb b/app/views/alchemy/essences/_essence_audio_view.html.erb deleted file mode 100644 index 7b9e706c9d..0000000000 --- a/app/views/alchemy/essences/_essence_audio_view.html.erb +++ /dev/null @@ -1,15 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_audio_view] %> -<%- if content.ingredient -%> - <%= content_tag :audio, - controls: content.essence.controls, - autoplay: content.essence.autoplay, - loop: content.essence.loop, - muted: content.essence.muted do %> - <%= tag :source, - src: alchemy.show_attachment_path( - content.ingredient, - format: content.ingredient.suffix - ), - type: content.ingredient.file_mime_type %> - <% end %> -<%- end -%> diff --git a/app/views/alchemy/essences/_essence_boolean_editor.html.erb b/app/views/alchemy/essences/_essence_boolean_editor.html.erb deleted file mode 100644 index 8f80f652db..0000000000 --- a/app/views/alchemy/essences/_essence_boolean_editor.html.erb +++ /dev/null @@ -1,11 +0,0 @@ -<%= content_tag :div, - id: essence_boolean_editor.dom_id, - class: essence_boolean_editor.css_classes, - data: essence_boolean_editor.data_attributes do %> - - <%= check_box_tag essence_boolean_editor.form_field_name, 1, essence_boolean_editor.ingredient %> - - <%= render_hint_for(essence_boolean_editor) %> -<% end %> diff --git a/app/views/alchemy/essences/_essence_boolean_view.html.erb b/app/views/alchemy/essences/_essence_boolean_view.html.erb deleted file mode 100644 index a2c8bdbed7..0000000000 --- a/app/views/alchemy/essences/_essence_boolean_view.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_boolean_view] %> -<%= Alchemy.t(content.ingredient) unless content.ingredient.nil? -%> \ No newline at end of file diff --git a/app/views/alchemy/essences/_essence_date_editor.html.erb b/app/views/alchemy/essences/_essence_date_editor.html.erb deleted file mode 100644 index d1890bcbb1..0000000000 --- a/app/views/alchemy/essences/_essence_date_editor.html.erb +++ /dev/null @@ -1,16 +0,0 @@ -<%= content_tag :div, - id: essence_date_editor.dom_id, - class: essence_date_editor.css_classes, - data: essence_date_editor.data_attributes do %> - <%= content_label(essence_date_editor) %> - <%= alchemy_datepicker( - essence_date_editor.essence, :date, { - name: essence_date_editor.form_field_name, - id: essence_date_editor.form_field_id, - value: essence_date_editor.ingredient - } - ) %> - -<% end %> diff --git a/app/views/alchemy/essences/_essence_date_view.html.erb b/app/views/alchemy/essences/_essence_date_view.html.erb deleted file mode 100644 index 57275a113a..0000000000 --- a/app/views/alchemy/essences/_essence_date_view.html.erb +++ /dev/null @@ -1,10 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_date_view] %> -<%- date_format = content.settings_value(:date_format, - local_assigns.fetch(:options, {})) -%> -<%- if content.ingredient.present? -%> -<%- if date_format == 'rfc822' -%> -<%= content.ingredient.to_s(:rfc822) %> -<%- else -%> -<%= l(content.ingredient, format: date_format) %> -<%- end -%> -<%- end -%> \ No newline at end of file diff --git a/app/views/alchemy/essences/_essence_file_editor.html.erb b/app/views/alchemy/essences/_essence_file_editor.html.erb deleted file mode 100644 index 7b6631c6cb..0000000000 --- a/app/views/alchemy/essences/_essence_file_editor.html.erb +++ /dev/null @@ -1,54 +0,0 @@ -<% dialog_link = link_to_dialog render_icon(:file, style: 'regular'), - alchemy.admin_attachments_path( - form_field_id: essence_file_editor.form_field_id(:attachment_id), - only: essence_file_editor.settings[:only], - except: essence_file_editor.settings[:except] - ), - { - title: Alchemy.t(:assign_file), - size: '780x585', - padding: false - }, - class: 'file_icon', - title: Alchemy.t(:assign_file) %> - -<%= content_tag :div, - id: essence_file_editor.dom_id, - class: essence_file_editor.css_classes, - data: essence_file_editor.data_attributes do %> - <%= content_label(essence_file_editor) %> -
- <% if essence_file_editor.ingredient %> -
- <%= render_icon(essence_file_editor.ingredient.icon_css_class) %> -
- <% end %> -
- <%= essence_file_editor.ingredient.try(:name) %> -
- <%= link_to render_icon(:times), "#", - class: [ - "remove_file_link", - essence_file_editor.ingredient ? nil : "hidden" - ], - data: { - form_field_id: essence_file_editor.form_field_id(:attachment_id) - } %> -
- <%= dialog_link %> - <%= link_to_dialog render_icon(:edit), - alchemy.polymorphic_url([ - :edit, - :admin, - essence_file_editor.essence - ]), - { - title: Alchemy.t(:edit_file_properties), - size: '400x215' - }, - title: Alchemy.t(:edit_file_properties) %> -
- <%= hidden_field_tag essence_file_editor.form_field_name(:attachment_id), - essence_file_editor.ingredient && essence_file_editor.ingredient.id %> -
-<% end %> diff --git a/app/views/alchemy/essences/_essence_file_view.html.erb b/app/views/alchemy/essences/_essence_file_view.html.erb deleted file mode 100644 index 4a08c4b36f..0000000000 --- a/app/views/alchemy/essences/_essence_file_view.html.erb +++ /dev/null @@ -1,18 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_file_view] %> -<%- if attachment = content.ingredient -%> -<%- html_options = local_assigns.fetch(:html_options, {}) -%> -<%= link_to( - content.essence.link_text.presence || - content.settings_value(:link_text, local_assigns.fetch(:options, {})) || - attachment.name, - attachment.url( - download: true, - name: attachment.slug, - format: attachment.suffix - ), - { - class: content.essence.css_class.presence, - title: content.essence.title.presence - }.merge(html_options) -) -%> -<%- end -%> diff --git a/app/views/alchemy/essences/_essence_headline_editor.html.erb b/app/views/alchemy/essences/_essence_headline_editor.html.erb deleted file mode 100644 index d8a0f63ce6..0000000000 --- a/app/views/alchemy/essences/_essence_headline_editor.html.erb +++ /dev/null @@ -1,36 +0,0 @@ -<%= content_tag :div, - id: essence_headline_editor.dom_id, - class: essence_headline_editor.css_classes, - data: essence_headline_editor.data_attributes do %> - <%= content_label(essence_headline_editor) %> - <%= text_field_tag( - essence_headline_editor.form_field_name, - essence_headline_editor.essence.body, - id: essence_headline_editor.form_field_id - ) %> - -
- <% essence = essence_headline_editor.essence %> - <% if essence.level_options.length > 1 %> -
- <%= label_tag Alchemy::EssenceHeadline.human_attribute_name(:level) %> - <%= select_tag( - essence_headline_editor.form_field_name(:level), - options_for_select(essence_headline_editor.essence.level_options, essence_headline_editor.essence.level), - class: "alchemy_selectbox full_width" - ) %> -
- <% end %> - - <% if essence.size_options.length > 1 %> -
- <%= label_tag Alchemy::EssenceHeadline.human_attribute_name(:size) %> - <%= select_tag( - essence_headline_editor.form_field_name(:size), - options_for_select(essence_headline_editor.essence.size_options, essence_headline_editor.essence.size), - class: "alchemy_selectbox full_width" - ) %> -
- <% end %> -
-<% end %> diff --git a/app/views/alchemy/essences/_essence_headline_view.html.erb b/app/views/alchemy/essences/_essence_headline_view.html.erb deleted file mode 100644 index 419a4b28f5..0000000000 --- a/app/views/alchemy/essences/_essence_headline_view.html.erb +++ /dev/null @@ -1,10 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_headline_view] %> -<%- html_options = local_assigns.fetch(:html_options, {}) -%> - -<%= content_tag "h#{content.essence.level}", - content.essence.ingredient, - class: [ - content.essence.size ? "h#{content.essence.size}" : nil, - html_options[:class] - ] -%> diff --git a/app/views/alchemy/essences/_essence_html_editor.html.erb b/app/views/alchemy/essences/_essence_html_editor.html.erb deleted file mode 100644 index b861ae5318..0000000000 --- a/app/views/alchemy/essences/_essence_html_editor.html.erb +++ /dev/null @@ -1,10 +0,0 @@ -<%= content_tag :div, - id: essence_html_editor.dom_id, - class: essence_html_editor.css_classes, - data: essence_html_editor.data_attributes do %> - <%= content_label(essence_html_editor) %> - <%= text_area_tag( - essence_html_editor.form_field_name, - essence_html_editor.ingredient - ) %> -<% end %> diff --git a/app/views/alchemy/essences/_essence_html_view.html.erb b/app/views/alchemy/essences/_essence_html_view.html.erb deleted file mode 100644 index 2c1ef63c78..0000000000 --- a/app/views/alchemy/essences/_essence_html_view.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_html_view] %> -<%= raw content.ingredient -%> \ No newline at end of file diff --git a/app/views/alchemy/essences/_essence_link_editor.html.erb b/app/views/alchemy/essences/_essence_link_editor.html.erb deleted file mode 100644 index 87126de447..0000000000 --- a/app/views/alchemy/essences/_essence_link_editor.html.erb +++ /dev/null @@ -1,30 +0,0 @@ -<%= content_tag :div, - id: essence_link_editor.dom_id, - class: essence_link_editor.css_classes, - data: essence_link_editor.data_attributes do %> - <%= content_label(essence_link_editor) %> - <%= text_field_tag '', essence_link_editor.ingredient, - class: "thin_border text_with_icon disabled", - name: nil, - id: nil, - disabled: true - %> - <%= hidden_field_tag essence_link_editor.form_field_name(:link), - essence_link_editor.essence.link, - "data-link-value": true %> - <%= hidden_field_tag essence_link_editor.form_field_name(:link_title), - essence_link_editor.essence.link_title, - "data-link-title": true %> - <%= hidden_field_tag essence_link_editor.form_field_name(:link_class_name), - essence_link_editor.essence.link_class_name, - "data-link-class": true %> - <%= hidden_field_tag essence_link_editor.form_field_name(:link_target), - essence_link_editor.essence.link_target, - "data-link-target": true %> - <%= render 'alchemy/essences/shared/linkable_essence_tools', content: essence_link_editor.content %> -<% end %> - diff --git a/app/views/alchemy/essences/_essence_link_view.html.erb b/app/views/alchemy/essences/_essence_link_view.html.erb deleted file mode 100644 index 54169d5954..0000000000 --- a/app/views/alchemy/essences/_essence_link_view.html.erb +++ /dev/null @@ -1,10 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_link_view] %> -<%- if content.ingredient.present? -%> -<%- html_options = { - target: content.essence.link_target == "blank" ? "_blank" : nil -}.merge(local_assigns.fetch(:html_options, {})) -%> -<%= link_to(content.ingredient, html_options) do -%> -<%= content.settings_value(:text, local_assigns.fetch(:options, {})) || - content.ingredient -%> -<%- end -%> -<%- end -%> \ No newline at end of file diff --git a/app/views/alchemy/essences/_essence_node_editor.html.erb b/app/views/alchemy/essences/_essence_node_editor.html.erb deleted file mode 100644 index c1b7ede5b1..0000000000 --- a/app/views/alchemy/essences/_essence_node_editor.html.erb +++ /dev/null @@ -1,27 +0,0 @@ -<%= content_tag :div, - id: essence_node_editor.dom_id, - class: essence_node_editor.css_classes, - data: essence_node_editor.data_attributes do %> - <%= content_label(essence_node_editor) %> - <%= text_field_tag( - essence_node_editor.form_field_name("node_id"), - essence_node_editor.essence.node_id, - id: essence_node_editor.form_field_id, - class: 'alchemy_selectbox full_width' - ) %> -<% end %> - - diff --git a/app/views/alchemy/essences/_essence_node_view.html.erb b/app/views/alchemy/essences/_essence_node_view.html.erb deleted file mode 100644 index f1b1ca8ccf..0000000000 --- a/app/views/alchemy/essences/_essence_node_view.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= render content.ingredient if content.ingredient %> diff --git a/app/views/alchemy/essences/_essence_page_editor.html.erb b/app/views/alchemy/essences/_essence_page_editor.html.erb deleted file mode 100644 index 41765f0425..0000000000 --- a/app/views/alchemy/essences/_essence_page_editor.html.erb +++ /dev/null @@ -1,26 +0,0 @@ -<%= content_tag :div, - id: essence_page_editor.dom_id, - class: essence_page_editor.css_classes, - data: essence_page_editor.data_attributes do %> - <%= content_label(essence_page_editor) %> - <%= text_field_tag( - essence_page_editor.form_field_name("page_id"), - essence_page_editor.essence.page_id, - id: essence_page_editor.form_field_id, - class: 'alchemy_selectbox full_width' - ) %> -<% end %> - - diff --git a/app/views/alchemy/essences/_essence_page_view.html.erb b/app/views/alchemy/essences/_essence_page_view.html.erb deleted file mode 100644 index 20ff10ab69..0000000000 --- a/app/views/alchemy/essences/_essence_page_view.html.erb +++ /dev/null @@ -1,5 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_page_view] %> -<% page = content.ingredient %> -<% if page %> -<%= link_to page.name, alchemy.show_page_path(urlname: page.urlname) %> -<% end %> \ No newline at end of file diff --git a/app/views/alchemy/essences/_essence_picture_editor.html.erb b/app/views/alchemy/essences/_essence_picture_editor.html.erb deleted file mode 100644 index c61d7ca1c1..0000000000 --- a/app/views/alchemy/essences/_essence_picture_editor.html.erb +++ /dev/null @@ -1,59 +0,0 @@ -<% options = local_assigns.fetch(:options, {}) %> - -<%= content_tag :div, - id: essence_picture_editor.dom_id, - class: essence_picture_editor.css_classes, - data: essence_picture_editor.data_attributes do %> - <%= content_label(essence_picture_editor) %> - <%= content_tag :div, - data: { - target_size: essence_picture_editor.essence.content.settings[:size] || [ - essence_picture_editor.essence.image_file_width.to_i, - essence_picture_editor.essence.image_file_height.to_i - ].join("x"), - image_cropper: essence_picture_editor.essence.thumbnail_url_options[:crop], - }, - class: "picture_thumbnail" do %> - - <%= render_icon(:times) %> - -
-
- <%- if essence_picture_editor.ingredient -%> - <%= essence_picture_thumbnail(essence_picture_editor) %> - <% else %> - <%= render_icon(:image, style: 'regular') %> - <% end %> -
-
- <%- if essence_picture_editor.essence.css_class.present? -%> -
- <%= Alchemy.t("alchemy.essence_pictures.css_classes.#{essence_picture_editor.essence.css_class}", - default: essence_picture_editor.essence.css_class.camelcase) %> -
- <%- end -%> -
- <%= render 'alchemy/essences/shared/essence_picture_tools', { - essence_picture_editor: essence_picture_editor - } %> -
- <% end %> - <%= hidden_field_tag essence_picture_editor.form_field_name(:picture_id), - essence_picture_editor.ingredient&.id, data: { - picture_id: true, - image_file_width: essence_picture_editor.ingredient&.image_file_width, - image_file_height: essence_picture_editor.ingredient&.image_file_height - } %> - <%= hidden_field_tag essence_picture_editor.form_field_name(:link), - essence_picture_editor.essence.link, data: { link_value: true }%> - <%= hidden_field_tag essence_picture_editor.form_field_name(:link_title), - essence_picture_editor.essence.link_title, data: { link_title: true } %> - <%= hidden_field_tag essence_picture_editor.form_field_name(:link_class_name), - essence_picture_editor.essence.link_class_name, data: { link_class: true } %> - <%= hidden_field_tag essence_picture_editor.form_field_name(:link_target), - essence_picture_editor.essence.link_target, data: { link_target: true } %> - <%= hidden_field_tag essence_picture_editor.form_field_name(:crop_from), - essence_picture_editor.essence.crop_from, data: { crop_from: true } %> - <%= hidden_field_tag essence_picture_editor.form_field_name(:crop_size), - essence_picture_editor.essence.crop_size, data: { crop_size: true } %> -<% end %> diff --git a/app/views/alchemy/essences/_essence_picture_view.html.erb b/app/views/alchemy/essences/_essence_picture_view.html.erb deleted file mode 100644 index 33777f6c8c..0000000000 --- a/app/views/alchemy/essences/_essence_picture_view.html.erb +++ /dev/null @@ -1,6 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_picture_view] %> -<%= Alchemy::EssencePictureView.new( - content, - local_assigns[:options] || {}, - local_assigns[:html_options] || {} -).render %> diff --git a/app/views/alchemy/essences/_essence_richtext_editor.html.erb b/app/views/alchemy/essences/_essence_richtext_editor.html.erb deleted file mode 100644 index 987de4f3e1..0000000000 --- a/app/views/alchemy/essences/_essence_richtext_editor.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -<%= content_tag :div, - id: essence_richtext_editor.dom_id, - class: essence_richtext_editor.css_classes, - data: essence_richtext_editor.data_attributes do %> - <%= content_label(essence_richtext_editor) %> -
- <%= text_area_tag( - essence_richtext_editor.form_field_name, - essence_richtext_editor.ingredient || '', - class: essence_richtext_editor.tinymce_class_name, - id: "tinymce_#{essence_richtext_editor.id}" - ) %> -
-<% end %> diff --git a/app/views/alchemy/essences/_essence_richtext_view.html.erb b/app/views/alchemy/essences/_essence_richtext_view.html.erb deleted file mode 100644 index f4b108e2dd..0000000000 --- a/app/views/alchemy/essences/_essence_richtext_view.html.erb +++ /dev/null @@ -1,4 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_richtext_view] %> -<%- options = local_assigns.fetch(:options, {}) -%> -<%- plain_text = !!content.settings_value(:plain_text, options) -%> -<%= raw content.essence.public_send(plain_text ? :stripped_body : :body) -%> \ No newline at end of file diff --git a/app/views/alchemy/essences/_essence_select_editor.html.erb b/app/views/alchemy/essences/_essence_select_editor.html.erb deleted file mode 100644 index 8aec570be1..0000000000 --- a/app/views/alchemy/essences/_essence_select_editor.html.erb +++ /dev/null @@ -1,28 +0,0 @@ -<% select_values = essence_select_editor.settings[:select_values] %> - -<%= content_tag :div, - id: essence_select_editor.dom_id, - class: [ - essence_select_editor.css_classes, - essence_select_editor.settings[:display_inline] ? 'display_inline' : '' - ], data: essence_select_editor.data_attributes do %> - <%= content_label(essence_select_editor) %> - - <% if select_values.nil? %> - <%= warning(':select_values is nil', - "No select values given. -
Please provide select_values on the - content definition settings in - elements.yml.") %> - <% else %> - <% - if select_values.is_a?(Hash) - options_tags = grouped_options_for_select(select_values, essence_select_editor.ingredient) - else - options_tags = options_for_select(select_values, essence_select_editor.ingredient) - end %> - <%= select_tag essence_select_editor.form_field_name, options_tags, { - class: ["alchemy_selectbox", "essence_editor_select"] - } %> - <% end %> -<% end %> diff --git a/app/views/alchemy/essences/_essence_select_view.html.erb b/app/views/alchemy/essences/_essence_select_view.html.erb deleted file mode 100644 index cd2cf9ad37..0000000000 --- a/app/views/alchemy/essences/_essence_select_view.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_select_view] %> -<%= content.ingredient %> \ No newline at end of file diff --git a/app/views/alchemy/essences/_essence_text_editor.html.erb b/app/views/alchemy/essences/_essence_text_editor.html.erb deleted file mode 100644 index 8774680fbd..0000000000 --- a/app/views/alchemy/essences/_essence_text_editor.html.erb +++ /dev/null @@ -1,29 +0,0 @@ -<%= content_tag :div, - id: essence_text_editor.dom_id, - class: [ - essence_text_editor.css_classes, - essence_text_editor.settings[:display_inline] ? 'display_inline' : '' - ], data: essence_text_editor.data_attributes do %> - <%= content_label(essence_text_editor) %> - <%= text_field_tag( - essence_text_editor.form_field_name, - essence_text_editor.ingredient, - class: "thin_border #{essence_text_editor.settings[:linkable] ? ' text_with_icon' : ''}", - type: essence_text_editor.settings[:input_type] || "text" - ) %> - <% if essence_text_editor.settings[:linkable] %> - <%= hidden_field_tag essence_text_editor.form_field_name(:link), - essence_text_editor.essence.link, - "data-link-value": true %> - <%= hidden_field_tag essence_text_editor.form_field_name(:link_title), - essence_text_editor.essence.link_title, - "data-link-title": true %> - <%= hidden_field_tag essence_text_editor.form_field_name(:link_class_name), - essence_text_editor.essence.link_class_name, - "data-link-class": true %> - <%= hidden_field_tag essence_text_editor.form_field_name(:link_target), - essence_text_editor.essence.link_target, - "data-link-target": true %> - <%= render 'alchemy/essences/shared/linkable_essence_tools', content: essence_text_editor.content %> - <% end %> -<% end %> diff --git a/app/views/alchemy/essences/_essence_text_view.html.erb b/app/views/alchemy/essences/_essence_text_view.html.erb deleted file mode 100644 index 3c3f847681..0000000000 --- a/app/views/alchemy/essences/_essence_text_view.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_text_view] %> -<%- options = local_assigns.fetch(:options, {}) -%> -<%- html_options = local_assigns.fetch(:html_options, {}) -%> -<%- if content.essence.link.blank? || - content.settings_value(:disable_link, options) -%> -<%= content.ingredient -%> -<%- else -%> -<%= link_to( - content.ingredient, - url_for(content.essence.link), - { - title: content.essence.link_title, - target: (content.essence.link_target == "blank" ? "_blank" : nil), - 'data-link-target' => content.essence.link_target - }.merge(html_options) -) -%> -<%- end -%> \ No newline at end of file diff --git a/app/views/alchemy/essences/_essence_video_editor.html.erb b/app/views/alchemy/essences/_essence_video_editor.html.erb deleted file mode 100644 index f27cc97511..0000000000 --- a/app/views/alchemy/essences/_essence_video_editor.html.erb +++ /dev/null @@ -1,4 +0,0 @@ -<%= render( - "alchemy/essences/essence_file_editor", - essence_file_editor: essence_video_editor -) %> diff --git a/app/views/alchemy/essences/_essence_video_view.html.erb b/app/views/alchemy/essences/_essence_video_view.html.erb deleted file mode 100644 index 7ca4443395..0000000000 --- a/app/views/alchemy/essences/_essence_video_view.html.erb +++ /dev/null @@ -1,19 +0,0 @@ -<% content = local_assigns[:content] || local_assigns[:essence_video_view] %> -<%- if content.ingredient -%> - <%= content_tag :video, - controls: content.essence.controls, - autoplay: content.essence.autoplay, - loop: content.essence.loop, - muted: content.essence.muted, - playsinline: content.essence.playsinline, - preload: content.essence.preload.presence, - width: content.essence.width.presence, - height: content.essence.height.presence do %> - <%= tag :source, - src: alchemy.show_attachment_path( - content.ingredient, - format: content.ingredient.suffix - ), - type: content.ingredient.file_mime_type %> - <% end %> -<%- end -%> diff --git a/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb b/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb deleted file mode 100644 index 5b7f302a60..0000000000 --- a/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +++ /dev/null @@ -1,59 +0,0 @@ -<% content = essence_picture_editor.essence.content %> -<% linkable = content.settings[:linkable] != false %> -<% croppable = content.essence && content.essence.allow_image_cropping? %> - -<%= link_to_dialog render_icon(:crop), - alchemy.crop_admin_essence_picture_path(content.essence, { - crop_from_form_field_id: essence_picture_editor.form_field_id(:crop_from), - crop_size_form_field_id: essence_picture_editor.form_field_id(:crop_size), - picture_id: content.essence.picture_id - }), { - size: "1080x615", - title: Alchemy.t('Edit Picturemask'), - image_loader: false, - padding: false - }, { - title: Alchemy.t('Edit Picturemask'), - class: croppable ? "crop_link" : "disabled crop_link", - tabindex: croppable ? nil : "-1", - onclick: "return false" - } %> - -<%= link_to_dialog render_icon('file-image', style: 'regular'), - alchemy.admin_pictures_path( - form_field_id: essence_picture_editor.form_field_id(:picture_id) - ), - { - title: (content.ingredient ? Alchemy.t(:swap_image) : Alchemy.t(:insert_image)), - size: '790x590', - padding: false - }, - title: (content.ingredient ? Alchemy.t(:swap_image) : Alchemy.t(:insert_image)) %> - -<%= link_to_if linkable, render_icon(:link), '', { - onclick: 'new Alchemy.LinkDialog(this).open(); return false;', - class: content.linked? ? 'linked' : nil, - title: Alchemy.t(:link_image), - "data-parent-selector": "##{content.dom_id}", - id: "edit_link_#{content.id}" -} do %> - <%= render_icon(:link) %> -<% end %> - -<%= link_to_if linkable, render_icon(:unlink), '', { - onclick: "return Alchemy.LinkDialog.removeLink(this, '##{content.dom_id}')", - class: content.linked? ? 'linked' : 'disabled', - tabindex: content.linked? ? nil : '-1', - title: Alchemy.t(:unlink) -} do %> - <%= render_icon(:unlink) %> -<% end %> - -<%= link_to_dialog render_icon(:edit), - alchemy.edit_admin_essence_picture_path( - id: content.essence.id, - content_id: content.id - ), { - title: Alchemy.t(:edit_image_properties), - size: edit_picture_dialog_size(content) - }, title: Alchemy.t(:edit_image_properties) %> diff --git a/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb b/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb deleted file mode 100644 index d5b538cf65..0000000000 --- a/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb +++ /dev/null @@ -1,20 +0,0 @@ - - <%= link_to( - render_icon(:link), - '#', - onclick: 'new Alchemy.LinkDialog(this).open(); return false;', - class: "icon_button#{content.linked? ? ' linked' : ''} link-essence", - "data-parent-selector": "##{content.dom_id}", - title: Alchemy.t(:place_link), - id: "edit_link_#{content.id}" - ) %> - <%= link_to( - render_icon(:unlink), - '#', - onclick: "return Alchemy.LinkDialog.removeLink(this, '##{content.dom_id}')", - class: "icon_button unlink-essence #{content.linked? ? 'linked' : 'disabled'}", - tabindex: content.linked? ? nil : '-1', - 'data-content-id' => content.id, - title: Alchemy.t(:unlink) - ) %> - diff --git a/app/views/alchemy/ingredients/_boolean_editor.html.erb b/app/views/alchemy/ingredients/_boolean_editor.html.erb index c8b1e65b17..1824432c9e 100644 --- a/app/views/alchemy/ingredients/_boolean_editor.html.erb +++ b/app/views/alchemy/ingredients/_boolean_editor.html.erb @@ -3,7 +3,7 @@ data: boolean_editor.data_attributes do %> <%= element_form.fields_for(:ingredients, boolean_editor.ingredient) do |f| %> <%= f.label :value, style: "display: inline-block" do %> - <%= f.check_box :value, id: nil %> + <%= f.check_box :value, id: boolean_editor.form_field_id %> <%= render_ingredient_role(boolean_editor) %> <% end %> <%= render_hint_for(boolean_editor) %> diff --git a/app/views/alchemy/ingredients/_headline_editor.html.erb b/app/views/alchemy/ingredients/_headline_editor.html.erb index a0ad4c383d..b13cec0900 100644 --- a/app/views/alchemy/ingredients/_headline_editor.html.erb +++ b/app/views/alchemy/ingredients/_headline_editor.html.erb @@ -6,7 +6,7 @@ data: headline_editor.data_attributes do %> <%= element_form.fields_for(:ingredients, headline_editor.ingredient) do |f| %> <%= ingredient_label(headline_editor) %> - <%= f.text_field :value, id: nil %> + <%= f.text_field :value, id: headline_editor.form_field_id %> <% if headline_editor.settings[:anchor] %> <%= render "alchemy/ingredients/shared/anchor", ingredient_editor: headline_editor %> diff --git a/app/views/alchemy/ingredients/_html_editor.html.erb b/app/views/alchemy/ingredients/_html_editor.html.erb index af2bf486f5..96c71762fe 100644 --- a/app/views/alchemy/ingredients/_html_editor.html.erb +++ b/app/views/alchemy/ingredients/_html_editor.html.erb @@ -3,6 +3,6 @@ data: html_editor.data_attributes do %> <%= element_form.fields_for(:ingredients, html_editor.ingredient) do |f| %> <%= ingredient_label(html_editor) %> - <%= f.text_area :value, id: nil %> + <%= f.text_area :value, id: html_editor.form_field_id %> <% end %> <% end %> diff --git a/app/views/alchemy/ingredients/_node_editor.html.erb b/app/views/alchemy/ingredients/_node_editor.html.erb index 26e8a12ebc..be99bc31ad 100644 --- a/app/views/alchemy/ingredients/_node_editor.html.erb +++ b/app/views/alchemy/ingredients/_node_editor.html.erb @@ -16,7 +16,7 @@ }) %> $('#<%= node_editor.form_field_id(:node_id) %>').alchemyNodeSelect({ placeholder: "<%= Alchemy.t(:search_node) %>", - url: "<%= alchemy.api_nodes_path %>", + url: "<%= alchemy.api_nodes_path(language_id: node_editor.page&.language_id) %>", query_params: <%== query_params.to_json %>, <% if node_editor.node %> <% serialized_node = ActiveModelSerializers::SerializableResource.new(node_editor.node, include: :ancestors) %> diff --git a/app/views/alchemy/ingredients/_select_editor.html.erb b/app/views/alchemy/ingredients/_select_editor.html.erb index 55f00dc511..20a6d9f867 100644 --- a/app/views/alchemy/ingredients/_select_editor.html.erb +++ b/app/views/alchemy/ingredients/_select_editor.html.erb @@ -22,7 +22,7 @@ options_tags = options_for_select(select_values, select_editor.value) end %> <%= f.select :value, options_tags, {}, { - id: nil, + id: select_editor.form_field_id, class: ["alchemy_selectbox", "ingredient-editor-select"] } %> <% end %> diff --git a/app/views/alchemy/ingredients/_text_editor.html.erb b/app/views/alchemy/ingredients/_text_editor.html.erb index 5724c7dd77..1f88ad8dc2 100644 --- a/app/views/alchemy/ingredients/_text_editor.html.erb +++ b/app/views/alchemy/ingredients/_text_editor.html.erb @@ -7,7 +7,7 @@ <%= ingredient_label(text_editor) %> <%= f.text_field :value, class: text_editor.settings[:linkable] ? "text_with_icon" : "", - id: nil, + id: text_editor.form_field_id, type: text_editor.settings[:input_type] || "text" %> <% if text_editor.settings[:anchor] %> <%= render "alchemy/ingredients/shared/anchor", ingredient_editor: text_editor %> diff --git a/config/locales/alchemy.en.yml b/config/locales/alchemy.en.yml index f171dc76ba..a6b9510768 100644 --- a/config/locales/alchemy.en.yml +++ b/config/locales/alchemy.en.yml @@ -1,9 +1,7 @@ en: - # = Alchemy Translations # All translations used in Alchemy CMS are inside this alchemy namespace. alchemy: - # == Translations for page_layout names # Just use the page_layouts name like defined inside the config/alchemy/page_layouts.yml file and translate it. # @@ -49,7 +47,6 @@ en: # content_names: - # === Translations for menu names # Used for the translations of the names of root menu nodes. # @@ -160,8 +157,8 @@ en: content_validations: errors: blank: "%{field} can't be blank" - invalid: '%{field} has wrong format' - taken: '%{field} has already been taken' + invalid: "%{field} has wrong format" + taken: "%{field} has already been taken" default_content_texts: lorem: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." @@ -169,9 +166,9 @@ en: essence_pictures: css_classes: - left: 'Left from text' - right: 'Right from text' - no_float: 'Above the text' + left: "Left from text" + right: "Right from text" + no_float: "Above the text" ingredient_values: boolean: @@ -181,32 +178,32 @@ en: # == Contactform translations contactform: labels: - salutation: 'Salutation' - choose: 'Please choose' - mr: 'Mr.' - mrs: 'Mrs.' - firstname: 'Firstname' - lastname: 'Lastname' - address: 'Street / No.' - zip: 'Zipcode / City' - phone: 'Telephone' - email: 'Email' - message: 'Message' - send: 'Send' - mandatory_fields: '*Mandatory fields.' + salutation: "Salutation" + choose: "Please choose" + mr: "Mr." + mrs: "Mrs." + firstname: "Firstname" + lastname: "Lastname" + address: "Street / No." + zip: "Zipcode / City" + phone: "Telephone" + email: "Email" + message: "Message" + send: "Send" + mandatory_fields: "*Mandatory fields." # The flash message shown after successfully sending the message. messages: - success: 'Your message was delivered successfully.' + success: "Your message was delivered successfully." # == Translated language names for translation select translations: - de: 'DE' - en: 'EN' - es: 'ES' - it: 'IT' - fr: 'FR' - nl: 'NL' - ru: 'RU' + de: "DE" + en: "EN" + es: "ES" + it: "IT" + fr: "FR" + nl: "NL" + ru: "RU" # == User roles translations user_roles: @@ -227,18 +224,18 @@ en: aliases: Enter additional domains this site should be accessible by. Please separate them by space or new line. add_nested_element: "Add %{name}" - anchor: 'Anchor' + anchor: "Anchor" anchor_link_headline: You can link to an anchor from the current page. automatic_anchor_notice: The anchor is generated automatically. attribute_fixed: Value can't be changed for this page type - back: 'back' + back: "back" locked_pages: "Active pages" "Add a page": "Add a page" "Add global page": "Add global page" "Add page link": "Add page link" "Alchemy is open software and itself uses open software and free resources:": "Alchemy is open software and itself uses open software and free resources:" - "Alchemy is up to date": 'Alchemy is up to date' - 'An error happened': 'An error happened' + "Alchemy is up to date": "Alchemy is up to date" + "An error happened": "An error happened" "Change password": "Change password" "Choose page": "Choose page" "Clear selection": "Clear selection" @@ -399,7 +396,7 @@ en: copy_page: "Copy page" "Could not delete Pictures": "Could not delete Pictures" copy_language_tree_heading: "Copy pages" - country_code_placeholder: 'i.e. US (optional)' + country_code_placeholder: "i.e. US (optional)" country_code_foot_note: "You only need to set a country code if you want to support multiple countries with the same language." create: "create" "Create language": "Create a new language" @@ -416,7 +413,7 @@ en: delete_menu: "Delete this menu" delete_node: "Delete this menu node" delete_page: "Delete this page" - delete_tag: 'Delete tag' + delete_tag: "Delete tag" document: "File" download_csv: "Download CSV" download_file: "Download file '%{filename}'" @@ -429,13 +426,13 @@ en: edit_node: "Edit menu node" edit_page: "Edit this page" edit_page_properties: "Edit page properties" - edit_tag: 'Edit tag' + edit_tag: "Edit tag" edit_selected_pictures: "Edit selected pictures" element_editor_not_found: "Error within this Element" element_of_type: "Element" element_saved: "Saved element." enter_external_link: "Please enter the URL you want to link with" - explain_cropping: "

Move the frame and change its size with the mouse or arrow keys to adjust the image mask. Click on \"apply\" when you are satisfied with your selection.

If you want to return to the original centered image mask like it was defined in the layout, click \"reset\" and \"apply\" afterwards.

" + explain_cropping: '

Move the frame and change its size with the mouse or arrow keys to adjust the image mask. Click on "apply" when you are satisfied with your selection.

If you want to return to the original centered image mask like it was defined in the layout, click "reset" and "apply" afterwards.

' explain_publishing: "Publish current page content" explain_unlocking: "Leave page and unlock it for other users." external_link_notice_1: "Please enter the complete url with http:// or a similar protocol." @@ -474,7 +471,7 @@ en: "item removed from clipboard": "Removed %{name} from clipboard" javascript_disabled_headline: "Javascript is disabled!" javascript_disabled_text: "Alchemy needs Javascript to run smoothly. Please enable it in your browser settings." - language_code_placeholder: 'i.e. en' + language_code_placeholder: "i.e. en" language_pages_copied: "Language tree successfully copied." left: "left" legacy_url_info_text: "A link is a redirect from an old URL to the current URL of this page. This redirect happens with a 301 status code." @@ -529,10 +526,10 @@ en: alchemy/site: "

You do not have any websites yet.

In order to serve requests you need to create a website first.

This form has been filled with sensible defaults that work in most cases.

" no_search_results: "Your search did not return any results." "not a valid image": "This is not an valid image." - "or": 'or' - or_replace_it_with_an_existing_tag: 'Or replace it with an existing tag' + "or": "or" + or_replace_it_with_an_existing_tag: "Or replace it with an existing tag" "Page created": "Page: '%{name}' created." - page_infos: 'Page info' + page_infos: "Page info" page_properties: "Page properties" page_public: "published" page_published: "Published page" @@ -567,26 +564,26 @@ en: position_in_text: "Position in text" preview_size: "Preview size" preview_sizes: - '240': '240px (small phone)' - '320': '320px (iPhone)' - '480': '480px (small Tablet)' - '768': '768px (iPad - Portrait)' - '1024': '1024px (iPad - Landscape)' - '1280': '1280px (Desktop)' + "240": "240px (small phone)" + "320": "320px (iPhone)" + "480": "480px (small Tablet)" + "768": "768px (iPad - Portrait)" + "1024": "1024px (iPad - Landscape)" + "1280": "1280px (Desktop)" preview_url: Preview publish_page_language_not_public: Cannot publish page if language is not public publish_page_not_allowed: You have not the permission to publish this page - recently_uploaded_only: 'Recently uploaded only' + recently_uploaded_only: "Recently uploaded only" "regular method": "Regular method" remove: "Remove" rename_file: "Rename this file." rename: "Rename" replace: replace replace_file: Replace file - 'Replaced Tag': "Tag '%{old_tag}' was replaced with '%{new_tag}'" + "Replaced Tag": "Tag '%{old_tag}' was replaced with '%{new_tag}'" resources: relation_select: - blank: '- none -' + blank: "- none -" right: "right" robot_follow: "robot may follow links." robot_index: "allow robot to index." @@ -600,7 +597,7 @@ en: show_eq: "Show EQ" show_navigation: "Show in navigation" show_page_in_sitemap: "Show page in sitemap." - signup_mail_delivery_error: 'Signup mail could not be delivered. Please check your mail settings.' + signup_mail_delivery_error: "Signup mail could not be delivered. Please check your mail settings." small_thumbnails: "Small thumbnails" subject: "Subject" successfully_added_element: "Successfully added new element." @@ -610,7 +607,7 @@ en: swap_image: "Change image" insert_image: "Insert image" tag_list: Tags - tags_get_created_if_used_the_first_time: 'Tags get created if used the first time.' + tags_get_created_if_used_the_first_time: "Tags get created if used the first time." this_picture_is_used_on_these_pages: "This picture is used on following pages" title: "Title" to_alchemy: "To Alchemy" @@ -651,9 +648,9 @@ en: "Successfully updated": "Successfully updated" "Successfully removed": "Successfully removed" "Nothing found": "Nothing found." - complete: 'Abgeschlossen' - "Update available": 'Update available' - "Update status unavailable": 'Update status unavailable' + complete: "Abgeschlossen" + "Update available": "Update available" + "Update status unavailable": "Update status unavailable" "Uploading": "Uploading" cannot_signup_more_then_once: "You can't signup more then once." confirm_to_delete_user: "Do you really want to delete this user?" @@ -671,11 +668,11 @@ en: # Simple form translations forms: - "yes": 'Yes' - "no": 'No' + "yes": "Yes" + "no": "No" required: - text: 'required' - mark: '*' + text: "required" + mark: "*" error_notification: default_message: "Please review the problems below:" @@ -701,9 +698,9 @@ en: alchemy/content: attributes: name: - taken: 'is already taken in this element.' + taken: "is already taken in this element." essence: - validation_failed: 'Validation failed.' + validation_failed: "Validation failed." alchemy/element: attributes: name: @@ -711,8 +708,8 @@ en: alchemy/language: attributes: language_code: - invalid: '^Format of languagecode is not valid. Please use exactly two lowercase characters.' - taken: 'is already taken for this country code.' + invalid: "^Format of languagecode is not valid. Please use exactly two lowercase characters." + taken: "is already taken for this country code." locale: missing_file: "Localization not found for given language code. Please choose an existing one." alchemy/page: @@ -752,15 +749,15 @@ en: level: Level size: Size alchemy/message: - salutation: 'Salutation' - firstname: 'Firstname' - lastname: 'Lastname' - address: 'Street / No.' - zip: 'Zipcode' + salutation: "Salutation" + firstname: "Firstname" + lastname: "Lastname" + address: "Street / No." + zip: "Zipcode" city: City - phone: 'Telephone' - email: 'Email' - message: 'Message' + phone: "Telephone" + email: "Email" + message: "Message" # Translations for Alchemy database models activerecord: @@ -769,7 +766,7 @@ en: alchemy/node: attributes: base: - essence_nodes_present: "This menu item is in use inside an Alchemy element on the following pages: %{page_names}." + node_ingredients_present: "This menu item is in use inside an Alchemy element on the following pages: %{page_names}." alchemy/site: attributes: languages: diff --git a/config/routes.rb b/config/routes.rb index ba60ca4cde..3879c9cad7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,8 +16,6 @@ end namespace :admin, { path: Alchemy.admin_path, constraints: Alchemy.admin_constraints } do - resources :contents, only: [:create] - resources :nodes resources :pages do @@ -41,7 +39,6 @@ end resources :elements do - resources :contents collection do post :order end @@ -73,20 +70,12 @@ end end - resources :essence_audios, only: [:edit, :update] - concern :croppable do member do get :crop end end - resources :essence_pictures, only: [:edit, :update], concerns: [:croppable] - - resources :essence_files, only: [:edit, :update] - - resources :essence_videos, only: [:edit, :update] - resources :ingredients, only: [:edit, :update], concerns: [:croppable] resources :legacy_page_urls @@ -125,13 +114,9 @@ resources :elements, only: :show namespace :api, defaults: { format: "json" } do - resources :contents, only: [:index, :show] resources :ingredients, only: [:index] - resources :elements, only: [:index, :show] do - get "/contents" => "contents#index", as: "contents" - get "/contents/:name" => "contents#show", as: "content" - end + resources :elements, only: [:index, :show] resources :pages, only: [:index] do get "elements" => "elements#index", as: "elements" diff --git a/db/migrate/20200226213334_alchemy_four_point_four.rb b/db/migrate/20200226213334_alchemy_four_point_four.rb index c37fe19467..16da133252 100644 --- a/db/migrate/20200226213334_alchemy_four_point_four.rb +++ b/db/migrate/20200226213334_alchemy_four_point_four.rb @@ -16,14 +16,6 @@ def up end end - unless table_exists?("alchemy_contents") - create_table "alchemy_contents" do |t| - t.string "name" - t.references "essence", null: false, polymorphic: true, index: { unique: true } - t.references "element", null: false - end - end - unless table_exists?("alchemy_elements") create_table "alchemy_elements" do |t| t.string "name" @@ -50,92 +42,6 @@ def up end end - unless table_exists?("alchemy_essence_booleans") - create_table "alchemy_essence_booleans" do |t| - t.boolean "value" - t.index ["value"], name: "index_alchemy_essence_booleans_on_value" - end - end - - unless table_exists?("alchemy_essence_dates") - create_table "alchemy_essence_dates" do |t| - t.datetime "date" - end - end - - unless table_exists?("alchemy_essence_files") - create_table "alchemy_essence_files" do |t| - t.references "attachment" - t.string "title" - t.string "css_class" - t.string "link_text" - end - end - - unless table_exists?("alchemy_essence_htmls") - create_table "alchemy_essence_htmls" do |t| - t.text "source" - end - end - - unless table_exists?("alchemy_essence_links") - create_table "alchemy_essence_links" do |t| - t.string "link" - t.string "link_title" - t.string "link_target" - t.string "link_class_name" - end - end - - unless table_exists?("alchemy_essence_pages") - create_table "alchemy_essence_pages" do |t| - t.references "page" - end - end - - unless table_exists?("alchemy_essence_pictures") - create_table "alchemy_essence_pictures" do |t| - t.references "picture" - t.string "caption" - t.string "title" - t.string "alt_tag" - t.string "link" - t.string "link_class_name" - t.string "link_title" - t.string "css_class" - t.string "link_target" - t.string "crop_from" - t.string "crop_size" - t.string "render_size" - end - end - - unless table_exists?("alchemy_essence_richtexts") - create_table "alchemy_essence_richtexts" do |t| - t.text "body" - t.text "stripped_body" - t.boolean "public" - end - end - - unless table_exists?("alchemy_essence_selects") - create_table "alchemy_essence_selects" do |t| - t.string "value" - t.index ["value"], name: "index_alchemy_essence_selects_on_value" - end - end - - unless table_exists?("alchemy_essence_texts") - create_table "alchemy_essence_texts" do |t| - t.text "body" - t.string "link" - t.string "link_title" - t.string "link_class_name" - t.boolean "public", default: false - t.string "link_target" - end - end - unless table_exists?("alchemy_folded_pages") create_table "alchemy_folded_pages" do |t| t.references "page", null: false, index: false @@ -262,18 +168,10 @@ def up end end - unless foreign_key_exists?("alchemy_contents", column: "element_id") - add_foreign_key "alchemy_contents", "alchemy_elements", column: "element_id", on_update: :cascade, on_delete: :cascade - end - unless foreign_key_exists?("alchemy_elements", column: "page_id") add_foreign_key "alchemy_elements", "alchemy_pages", column: "page_id", on_update: :cascade, on_delete: :cascade end - unless foreign_key_exists?("alchemy_essence_pages", column: "page_id") - add_foreign_key "alchemy_essence_pages", "alchemy_pages", column: "page_id" - end - unless foreign_key_exists?("alchemy_nodes", column: "language_id") add_foreign_key "alchemy_nodes", "alchemy_languages", column: "language_id" end @@ -289,19 +187,8 @@ def up def down drop_table "alchemy_attachments" if table_exists?("alchemy_attachments") - drop_table "alchemy_contents" if table_exists?("alchemy_contents") drop_table "alchemy_elements" if table_exists?("alchemy_elements") drop_table "alchemy_elements_alchemy_pages" if table_exists?("alchemy_elements_alchemy_pages") - drop_table "alchemy_essence_booleans" if table_exists?("alchemy_essence_booleans") - drop_table "alchemy_essence_dates" if table_exists?("alchemy_essence_dates") - drop_table "alchemy_essence_files" if table_exists?("alchemy_essence_files") - drop_table "alchemy_essence_htmls" if table_exists?("alchemy_essence_htmls") - drop_table "alchemy_essence_links" if table_exists?("alchemy_essence_links") - drop_table "alchemy_essence_pages" if table_exists?("alchemy_essence_pages") - drop_table "alchemy_essence_pictures" if table_exists?("alchemy_essence_pictures") - drop_table "alchemy_essence_richtexts" if table_exists?("alchemy_essence_richtexts") - drop_table "alchemy_essence_selects" if table_exists?("alchemy_essence_selects") - drop_table "alchemy_essence_texts" if table_exists?("alchemy_essence_texts") drop_table "alchemy_folded_pages" if table_exists?("alchemy_folded_pages") drop_table "alchemy_languages" if table_exists?("alchemy_languages") drop_table "alchemy_legacy_page_urls" if table_exists?("alchemy_legacy_page_urls") diff --git a/db/migrate/20200423073425_create_alchemy_essence_nodes.rb b/db/migrate/20200423073425_create_alchemy_essence_nodes.rb deleted file mode 100644 index 50025e9ada..0000000000 --- a/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -class CreateAlchemyEssenceNodes < ActiveRecord::Migration[6.0] - def change - create_table :alchemy_essence_nodes do |t| - t.references "node" - t.timestamps - end - add_foreign_key "alchemy_essence_nodes", "alchemy_nodes", column: "node_id" - end -end diff --git a/db/migrate/20200907111332_remove_tri_state_booleans.rb b/db/migrate/20200907111332_remove_tri_state_booleans.rb index eccde1e34b..9ce50a2bbd 100644 --- a/db/migrate/20200907111332_remove_tri_state_booleans.rb +++ b/db/migrate/20200907111332_remove_tri_state_booleans.rb @@ -8,11 +8,6 @@ def change change_column_null :alchemy_elements, :folded, false change_column_null :alchemy_elements, :unique, false - change_column_null :alchemy_essence_richtexts, :public, false, false - change_column_default :alchemy_essence_richtexts, :public, false - - change_column_null :alchemy_essence_texts, :public, false - change_column_null :alchemy_folded_pages, :folded, false change_column_null :alchemy_languages, :public, false diff --git a/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb b/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb deleted file mode 100644 index 4b558f6299..0000000000 --- a/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -class AddSanitizedBodyToAlchemyEssenceRichtexts < ActiveRecord::Migration[6.0] - def change - add_column :alchemy_essence_richtexts, :sanitized_body, :text - end -end diff --git a/db/migrate/20210406093436_add_alchemy_essence_headlines.rb b/db/migrate/20210406093436_add_alchemy_essence_headlines.rb deleted file mode 100644 index c8442b4ba3..0000000000 --- a/db/migrate/20210406093436_add_alchemy_essence_headlines.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -class AddAlchemyEssenceHeadlines < ActiveRecord::Migration[6.0] - def change - create_table :alchemy_essence_headlines do |t| - t.text :body - t.integer :level - t.integer :size - t.timestamps - end - end -end diff --git a/db/migrate/20210506135919_create_essence_audios.rb b/db/migrate/20210506135919_create_essence_audios.rb deleted file mode 100644 index 47677a0fdf..0000000000 --- a/db/migrate/20210506135919_create_essence_audios.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -class CreateEssenceAudios < ActiveRecord::Migration[6.0] - def up - return if table_exists? :alchemy_essence_audios - - create_table :alchemy_essence_audios do |t| - t.references :attachment - t.boolean :controls, default: true, null: false - t.boolean :autoplay, default: false - t.boolean :loop, default: false, null: false - t.boolean :muted, default: false, null: false - end - end - - def down - drop_table :alchemy_essence_audios - end -end diff --git a/db/migrate/20210506140258_create_essence_videos.rb b/db/migrate/20210506140258_create_essence_videos.rb deleted file mode 100644 index d905e0d576..0000000000 --- a/db/migrate/20210506140258_create_essence_videos.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -class CreateEssenceVideos < ActiveRecord::Migration[6.0] - def up - return if table_exists? :alchemy_essence_videos - - create_table :alchemy_essence_videos do |t| - t.references :attachment - t.string :width - t.string :height - t.boolean :allow_fullscreen, default: true, null: false - t.boolean :autoplay, default: false, null: false - t.boolean :controls, default: true, null: false - t.boolean :loop, default: false, null: false - t.boolean :muted, default: false, null: false - t.string :preload - end - end - - def down - drop_table :alchemy_essence_videos - end -end diff --git a/db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb b/db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb deleted file mode 100644 index 14d78dc5b4..0000000000 --- a/db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class AddPlaysinlineToAlchemyEssenceVideos < ActiveRecord::Migration[6.0] - def change - return if column_exists?(:alchemy_essence_videos, :playsinline) - - add_column :alchemy_essence_videos, :playsinline, :boolean, default: false, null: false - end -end diff --git a/lib/alchemy/deprecation.rb b/lib/alchemy/deprecation.rb index 344759ab3f..a7864e1574 100644 --- a/lib/alchemy/deprecation.rb +++ b/lib/alchemy/deprecation.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true module Alchemy - Deprecation = ActiveSupport::Deprecation.new("6.1", "Alchemy") + Deprecation = ActiveSupport::Deprecation.new("8.0", "Alchemy") end diff --git a/lib/alchemy/essence.rb b/lib/alchemy/essence.rb deleted file mode 100644 index d329d6891b..0000000000 --- a/lib/alchemy/essence.rb +++ /dev/null @@ -1,250 +0,0 @@ -# frozen_string_literal: true - -require "active_record" - -module Alchemy #:nodoc: - module Essence #:nodoc: - def self.included(base) - base.extend(ClassMethods) - end - - # Delivers various methods we need for Essences in Alchemy. - # - # To turn a model into an essence call acts_as_essence inside your model and you will get: - # * validations - # * several getters (ie: page, element, content, ingredient, preview_text) - # - module ClassMethods - # Turn any active record model into an essence by calling this class method - # - # @option options [String || Symbol] ingredient_column ('body') - # specifies the column name you use for storing the content in the database (default: +body+) - # @option options [String || Symbol] validate_column (ingredient_column) - # The column the the validations run against. - # @option options [String || Symbol] preview_text_column (ingredient_column) - # Specify the column for the preview_text method. - # @deprecated - def acts_as_essence(options = {}) - if !DEPRECATED_ESSENCE_CLASSES.include?(name) - Alchemy::Deprecation.warn "Please create a custom Alchemy::Ingredient for #{name} instead" - end - - register_as_essence_association! - - configuration = { - ingredient_column: "body", - }.update(options) - - class_eval <<-RUBY, __FILE__, __LINE__ + 1 - attr_writer :validation_errors - include Alchemy::Essence::InstanceMethods - - validate :validate_ingredient, on: :update, if: -> { validations.any? } - - has_one :content, as: :essence, class_name: "Alchemy::Content", inverse_of: :essence - has_one :element, through: :content, class_name: "Alchemy::Element" - has_one :page, through: :element, class_name: "Alchemy::Page" - - scope :available, -> { joins(:element).merge(Alchemy::Element.published) } - scope :from_element, ->(name) { joins(:element).where(Element.table_name => { name: name }) } - - delegate :restricted?, to: :page, allow_nil: true - delegate :public?, to: :element, allow_nil: true - - after_update :touch_element - - def acts_as_essence_class - #{name} - end - - def ingredient_column - '#{configuration[:ingredient_column]}' - end - - def validation_column - '#{configuration[:validate_column] || configuration[:ingredient_column]}' - end - - def preview_text_column - '#{configuration[:preview_text_column] || configuration[:ingredient_column]}' - end - RUBY - - if configuration[:belongs_to] - class_eval <<-RUBY, __FILE__, __LINE__ + 1 - belongs_to :ingredient_association, **#{configuration[:belongs_to]} - - alias_method :#{configuration[:ingredient_column]}, :ingredient_association - alias_method :#{configuration[:ingredient_column]}=, :ingredient_association= - RUBY - end - end - - private - - # Register the current class as has_many association on +Alchemy::Page+ and +Alchemy::Element+ models - def register_as_essence_association! - klass_name = model_name.to_s - arguments = [:has_many, klass_name.demodulize.tableize.to_sym] - kwargs = { through: :contents, source: :essence, source_type: klass_name } - %w(Page Element).each { |k| "Alchemy::#{k}".constantize.send(*arguments, **kwargs) } - end - end - - module InstanceMethods - # Essence Validations: - # - # Essence validations can be set inside the config/elements.yml file. - # - # Supported validations are: - # - # * presence - # * uniqueness - # * format - # - # format needs to come with a regex or a predefined matcher string as its value. - # There are already predefined format matchers listed in the config/alchemy/config.yml file. - # It is also possible to add own format matchers there. - # - # Example of format matchers in config/alchemy/config.yml: - # - # format_matchers: - # email: !ruby/regexp '/\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/' - # url: !ruby/regexp '/\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?\z/ix' - # ssl: !ruby/regexp '/https:\/\/[\S]+/' - # - # Example of an element definition with essence validations: - # - # - name: person - # contents: - # - name: name - # type: EssenceText - # validate: [presence] - # - name: email - # type: EssenceText - # validate: [format: 'email'] - # - name: homepage - # type: EssenceText - # validate: [format: !ruby/regexp '^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$'] - # - # Example of an element definition with chained validations. - # - # - name: person - # contents: - # - name: name - # type: EssenceText - # validate: [presence, uniqueness, format: 'name'] - # - def validate_ingredient - validations.each do |validation| - if validation.respond_to?(:keys) - validation.map do |key, value| - send("validate_#{key}", value) - end - else - send("validate_#{validation}") - end - end - end - - def validations - @validations ||= definition.present? ? definition["validate"] || [] : [] - end - - def validation_errors - @validation_errors ||= [] - end - - def validate_presence(validate = true) - if validate && ingredient.blank? - errors.add(ingredient_column, :blank) - validation_errors << :blank - end - end - - def validate_uniqueness(validate = true) - return if !validate || !public? - - if duplicates.any? - errors.add(ingredient_column, :taken) - validation_errors << :taken - end - end - - def validate_format(format) - matcher = Config.get("format_matchers")[format] || format - if ingredient.to_s.match(Regexp.new(matcher)).nil? - errors.add(ingredient_column, :invalid) - validation_errors << :invalid - end - end - - def duplicates - acts_as_essence_class - .available - .from_element(element.name) - .where(ingredient_column.to_s => ingredient) - .where.not(id: id) - end - - # Returns the value stored from the database column that is configured as ingredient column. - def ingredient - if respond_to?(ingredient_column) - send(ingredient_column) - end - end - - # Sets the value stored in the database column that is configured as ingredient column. - def ingredient=(value) - if respond_to?(ingredient_setter_method) - send(ingredient_setter_method, value) - end - end - - # Returns the setter method for ingredient column - def ingredient_setter_method - ingredient_column.to_s + "=" - end - - # Essence definition from config/elements.yml - def definition - return {} if element.nil? || element.content_definitions.nil? - - element.content_definitions.detect { |c| c["name"] == content.name } || {} - end - - # Touches element. Called after save. - def touch_element - element&.touch - end - - # Returns the first x (default 30) characters of ingredient for the Element#preview_text method. - # - def preview_text(maxlength = 30) - send(preview_text_column).to_s[0..maxlength - 1] - end - - def open_link_in_new_window? - respond_to?(:link_target) && link_target == "blank" - end - - def partial_name - self.class.name.split("::").last.underscore - end - - def acts_as_essence? - acts_as_essence_class.present? - end - - def to_partial_path - "alchemy/essences/#{partial_name}_view" - end - - def has_tinymce? - false - end - end - end -end - -ActiveRecord::Base.include(Alchemy::Essence) diff --git a/lib/alchemy/permissions.rb b/lib/alchemy/permissions.rb index b0bb62443c..b0a954586e 100644 --- a/lib/alchemy/permissions.rb +++ b/lib/alchemy/permissions.rb @@ -37,10 +37,6 @@ module GuestUser def alchemy_guest_user_rules can([:show, :download], Alchemy::Attachment) { |a| !a.restricted? } - can :read, Alchemy::Content, Alchemy::Content.available.not_restricted do |c| - c.public? && !c.restricted? - end - can :read, Alchemy::Element, Alchemy::Element.published.not_restricted do |e| e.public? && !e.restricted? end @@ -64,10 +60,6 @@ def alchemy_member_rules # Resources can [:show, :download], Alchemy::Attachment - can :read, Alchemy::Content, Alchemy::Content.available do |c| - c.public? - end - can :read, Alchemy::Element, Alchemy::Element.published do |e| e.public? end @@ -109,12 +101,7 @@ def alchemy_author_rules # Resources can [:read, :download], Alchemy::Attachment - can :manage, Alchemy::Content can :manage, Alchemy::Element - can :manage, Alchemy::EssenceAudio - can :manage, Alchemy::EssenceFile - can :manage, Alchemy::EssencePicture - can :manage, Alchemy::EssenceVideo can :manage, Alchemy::Ingredient can [:crop], Alchemy::Ingredients::Picture can :manage, Alchemy::LegacyPageUrl diff --git a/lib/alchemy/test_support/essence_shared_examples.rb b/lib/alchemy/test_support/essence_shared_examples.rb deleted file mode 100644 index a89907151e..0000000000 --- a/lib/alchemy/test_support/essence_shared_examples.rb +++ /dev/null @@ -1,271 +0,0 @@ -# frozen_string_literal: true - -require "shoulda-matchers" - -RSpec.shared_examples_for "an essence" do - let(:element) { Alchemy::Element.new } - let(:content) { Alchemy::Content.new(name: "foo") } - let(:content_definition) { { "name" => "foo" } } - - it "touches the element after save" do - element = FactoryBot.create(:alchemy_element) - content = FactoryBot.create(:alchemy_content, element: element, essence: essence, essence_type: essence.class.name) - - element.update_column(:updated_at, 3.days.ago) - content.essence.update(essence.ingredient_column.to_sym => ingredient_value) - - element.reload - expect(element.updated_at).to be_within(3.seconds).of(Time.current) - end - - it "should have correct partial path" do - underscored_essence = essence.class.name.demodulize.underscore - expect(essence.to_partial_path).to eq("alchemy/essences/#{underscored_essence}_view") - end - - describe "#definition" do - subject { essence.definition } - - context "without element" do - it { is_expected.to eq({}) } - end - - context "with element" do - before do - expect(essence).to receive(:element).at_least(:once).and_return(element) - end - - context "but without content definitions" do - it { is_expected.to eq({}) } - end - - context "and content definitions" do - before do - allow(essence).to receive(:content).and_return(content) - end - - context "containing the content name" do - before do - expect(element).to receive(:content_definitions).at_least(:once).and_return([content_definition]) - end - - it "returns the content definition" do - is_expected.to eq(content_definition) - end - end - - context "not containing the content name" do - before do - expect(element).to receive(:content_definitions).at_least(:once).and_return([]) - end - - it { is_expected.to eq({}) } - end - end - end - end - - describe "#ingredient=" do - it "should set the value to ingredient column" do - essence.ingredient = ingredient_value - expect(essence.ingredient).to eq ingredient_value - end - end - - describe "validations" do - context "without essence definition in elements.yml" do - it "should return an empty array" do - allow(essence).to receive(:definition).and_return nil - expect(essence.validations).to eq([]) - end - end - - context "without validations defined in essence definition in elements.yml" do - it "should return an empty array" do - allow(essence).to receive(:definition).and_return({ name: "test", type: "EssenceText" }) - expect(essence.validations).to eq([]) - end - end - - describe "presence" do - context "with string given as validation type" do - before do - allow(essence).to receive(:definition).and_return({ "validate" => ["presence"] }) - end - - context "when the ingredient column is empty" do - before do - essence.update(essence.ingredient_column.to_sym => nil) - end - - it "should not be valid" do - expect(essence).to_not be_valid - end - end - - context "when the ingredient column is not nil" do - before do - essence.update(essence.ingredient_column.to_sym => ingredient_value) - end - - it "should be valid" do - expect(essence).to be_valid - end - end - end - - context "with hash given as validation type" do - context "where the value is true" do - before do - allow(essence).to receive(:definition).and_return({ "validate" => [{ "presence" => true }] }) - end - - context "when the ingredient column is empty" do - before do - essence.update(essence.ingredient_column.to_sym => nil) - end - - it "should not be valid" do - expect(essence).to_not be_valid - end - end - - context "when the ingredient column is not nil" do - before do - essence.update(essence.ingredient_column.to_sym => ingredient_value) - end - - it "should be valid" do - expect(essence).to be_valid - end - end - end - - context "where the value is false" do - before do - allow(essence).to receive(:definition).and_return({ "validate" => [{ "presence" => false }] }) - end - - it "should be valid" do - expect(essence).to be_valid - end - end - end - end - - describe "uniqueness" do - before do - allow(essence).to receive(:element).and_return(FactoryBot.create(:alchemy_element)) - essence.update(essence.ingredient_column.to_sym => ingredient_value) - end - - context "with string given as validation type" do - before do - expect(essence).to receive(:definition).at_least(:once).and_return({ "validate" => ["uniqueness"] }) - end - - context "when a duplicate exists" do - before do - allow(essence).to receive(:duplicates).and_return([essence.dup]) - end - - it "should not be valid" do - expect(essence).to_not be_valid - end - - context "when validated essence is not public" do - before do - expect(essence).to receive(:public?).and_return(false) - end - - it "should be valid" do - expect(essence).to be_valid - end - end - end - - context "when no duplicate exists" do - before do - expect(essence).to receive(:duplicates).and_return([]) - end - - it "should be valid" do - expect(essence).to be_valid - end - end - end - - context "with hash given as validation type" do - context "where the value is true" do - before do - expect(essence).to receive(:definition).at_least(:once).and_return({ "validate" => [{ "uniqueness" => true }] }) - end - - context "when a duplicate exists" do - before do - allow(essence).to receive(:duplicates).and_return([essence.dup]) - end - - it "should not be valid" do - expect(essence).to_not be_valid - end - - context "when validated essence is not public" do - before do - expect(essence).to receive(:public?).and_return(false) - end - - it "should be valid" do - expect(essence).to be_valid - end - end - end - - context "when no duplicate exists" do - before do - expect(essence).to receive(:duplicates).and_return([]) - end - - it "should be valid" do - expect(essence).to be_valid - end - end - end - - context "where the value is false" do - before do - allow(essence).to receive(:definition).and_return({ "validate" => [{ "uniqueness" => false }] }) - end - - it "should be valid" do - expect(essence).to be_valid - end - end - end - end - - describe "#acts_as_essence?" do - it "should return true" do - expect(essence.acts_as_essence?).to be_truthy - end - end - end - - context "delegations" do - it { should delegate_method(:restricted?).to(:page) } - it { should delegate_method(:public?).to(:element) } - end - - describe "essence relations" do - let(:page) { FactoryBot.create(:alchemy_page, :restricted) } - let(:element) { FactoryBot.create(:alchemy_element) } - - it "registers itself on page as essence relation" do - expect(page.respond_to?(essence.class.model_name.route_key)).to be(true) - end - - it "registers itself on element as essence relation" do - expect(element.respond_to?(essence.class.model_name.route_key)).to be(true) - end - end -end diff --git a/lib/alchemy/test_support/factories/content_factory.rb b/lib/alchemy/test_support/factories/content_factory.rb deleted file mode 100644 index 514aad0db9..0000000000 --- a/lib/alchemy/test_support/factories/content_factory.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :alchemy_content, class: "Alchemy::Content" do - name { "text" } - essence_type { "Alchemy::EssenceText" } - association :essence, factory: :alchemy_essence_text - association :element, factory: :alchemy_element - - trait :essence_file do - essence_type { "Alchemy::EssenceFile" } - association :essence, factory: :alchemy_essence_file - end - - trait :essence_picture do - essence_type { "Alchemy::EssencePicture" } - association :essence, factory: :alchemy_essence_picture - end - end -end diff --git a/lib/alchemy/test_support/factories/element_factory.rb b/lib/alchemy/test_support/factories/element_factory.rb index 7db7670c46..69908f55b6 100644 --- a/lib/alchemy/test_support/factories/element_factory.rb +++ b/lib/alchemy/test_support/factories/element_factory.rb @@ -3,7 +3,6 @@ FactoryBot.define do factory :alchemy_element, class: "Alchemy::Element" do name { "article" } - autogenerate_contents { false } autogenerate_ingredients { false } association :page_version, factory: :alchemy_page_version @@ -26,12 +25,7 @@ name { "slide" } end - trait :with_contents do - autogenerate_contents { true } - end - trait :with_ingredients do - name { "element_with_ingredients" } autogenerate_ingredients { true } end end diff --git a/lib/alchemy/test_support/factories/essence_audio_factory.rb b/lib/alchemy/test_support/factories/essence_audio_factory.rb deleted file mode 100644 index 71a22abe0a..0000000000 --- a/lib/alchemy/test_support/factories/essence_audio_factory.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :alchemy_essence_audio, class: "Alchemy::EssenceAudio" do - attachment factory: :alchemy_attachment - end -end diff --git a/lib/alchemy/test_support/factories/essence_file_factory.rb b/lib/alchemy/test_support/factories/essence_file_factory.rb deleted file mode 100644 index 82f11e0f7c..0000000000 --- a/lib/alchemy/test_support/factories/essence_file_factory.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :alchemy_essence_file, class: "Alchemy::EssenceFile" do - attachment factory: :alchemy_attachment - end -end diff --git a/lib/alchemy/test_support/factories/essence_page_factory.rb b/lib/alchemy/test_support/factories/essence_page_factory.rb deleted file mode 100644 index b44fc67602..0000000000 --- a/lib/alchemy/test_support/factories/essence_page_factory.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :alchemy_essence_page, class: "Alchemy::EssencePage" do - page factory: :alchemy_page - end -end diff --git a/lib/alchemy/test_support/factories/essence_picture_factory.rb b/lib/alchemy/test_support/factories/essence_picture_factory.rb deleted file mode 100644 index f7d56bd71f..0000000000 --- a/lib/alchemy/test_support/factories/essence_picture_factory.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :alchemy_essence_picture, class: "Alchemy::EssencePicture" do - picture factory: :alchemy_picture - - trait :with_content do - association :content, factory: :alchemy_content - end - end -end diff --git a/lib/alchemy/test_support/factories/essence_text_factory.rb b/lib/alchemy/test_support/factories/essence_text_factory.rb deleted file mode 100644 index a093182962..0000000000 --- a/lib/alchemy/test_support/factories/essence_text_factory.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :alchemy_essence_text, class: "Alchemy::EssenceText" do - body { "This is a headline" } - end -end diff --git a/lib/alchemy/test_support/factories/essence_video_factory.rb b/lib/alchemy/test_support/factories/essence_video_factory.rb deleted file mode 100644 index 75032f0f29..0000000000 --- a/lib/alchemy/test_support/factories/essence_video_factory.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :alchemy_essence_video, class: "Alchemy::EssenceVideo" do - attachment factory: :alchemy_attachment - end -end diff --git a/lib/alchemy/test_support/factories/page_factory.rb b/lib/alchemy/test_support/factories/page_factory.rb index 3b50dd0972..221b578888 100644 --- a/lib/alchemy/test_support/factories/page_factory.rb +++ b/lib/alchemy/test_support/factories/page_factory.rb @@ -42,10 +42,12 @@ after(:create) do |page| if page.autogenerate_elements page.definition["autogenerate"].each do |name| - create(:alchemy_element, + create( + :alchemy_element, name: name, page_version: page.public_version, - autogenerate_contents: true) + autogenerate_ingredients: true, + ) end end end diff --git a/lib/alchemy/upgrader/six_point_zero.rb b/lib/alchemy/upgrader/six_point_zero.rb index e8384615ce..0a4900273e 100644 --- a/lib/alchemy/upgrader/six_point_zero.rb +++ b/lib/alchemy/upgrader/six_point_zero.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require_relative "tasks/add_page_versions" -require_relative "tasks/ingredients_migrator" module Alchemy class Upgrader::SixPointZero < Upgrader @@ -10,12 +9,6 @@ def create_public_page_versions desc "Create public page versions for pages" Alchemy::Upgrader::Tasks::AddPageVersions.new.create_public_page_versions end - - def create_ingredients - desc "Create ingredients for elements with ingredients defined" - Alchemy::Upgrader::Tasks::IngredientsMigrator.new.create_ingredients - log "Done.", :success - end end end end diff --git a/lib/alchemy/upgrader/tasks/ingredients_migrator.rb b/lib/alchemy/upgrader/tasks/ingredients_migrator.rb deleted file mode 100644 index 1ebf2fafbf..0000000000 --- a/lib/alchemy/upgrader/tasks/ingredients_migrator.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -require "alchemy/upgrader" - -module Alchemy::Upgrader::Tasks - class IngredientsMigrator < Thor - include Thor::Actions - - no_tasks do - def create_ingredients(verbose: !Rails.env.test?) - Alchemy::Deprecation.silence do - elements_with_ingredients = Alchemy::ElementDefinition.all.select { |d| d.key?(:ingredients) } - if ENV["ONLY"] - elements_with_ingredients = elements_with_ingredients.select { |d| d[:name].in? ENV["ONLY"].split(",") } - end - # eager load all elements that have ingredients defined but no ingredient records yet. - all_elements = Alchemy::Element - .named(elements_with_ingredients.map { |d| d[:name] }) - .preload(contents: :essence) - .left_outer_joins(:ingredients).where(alchemy_ingredients: { id: nil }) - .to_a - elements_with_ingredients.map do |element_definition| - elements = all_elements.select { |e| e.name == element_definition[:name] } - if elements.any? - puts "-- Creating ingredients for #{elements.count} #{element_definition[:name]}(s)" if verbose - elements.each do |element| - MigrateElementIngredients.call(element) - print "." if verbose - end - puts "\n" if verbose - elsif verbose - puts "-- No #{element_definition[:name]} elements found for migration." - end - end - end - end - end - - class MigrateElementIngredients - def self.call(element) - Alchemy::Element.transaction do - element.definition[:ingredients].each do |ingredient_definition| - ingredient = element.ingredients.build( - role: ingredient_definition[:role], - type: Alchemy::Ingredient.normalize_type(ingredient_definition[:type]), - ) - - content = element.content_by_name(ingredient_definition[:role]) - if content - essence = content.essence - if essence - belongs_to_associations = essence.class.reflect_on_all_associations(:belongs_to) - if belongs_to_associations.any? - ingredient.related_object = essence.public_send(belongs_to_associations.first.name) - else - ingredient.value = content.ingredient - end - data = ingredient.class.stored_attributes.fetch(:data, []).each_with_object({}) do |attr, d| - next unless essence.respond_to?(attr) - - d[attr] = essence.public_send(attr) - end - ingredient.data = data - end - content.destroy! - end - - ingredient.save! - end - end - end - end - end -end diff --git a/lib/alchemy_cms.rb b/lib/alchemy_cms.rb index 4e94e43f50..5aa95ca467 100644 --- a/lib/alchemy_cms.rb +++ b/lib/alchemy_cms.rb @@ -39,7 +39,6 @@ require_relative "alchemy/elements_finder" require_relative "alchemy/error_tracking" require_relative "alchemy/errors" -require_relative "alchemy/essence" require_relative "alchemy/filetypes" require_relative "alchemy/forms/builder" require_relative "alchemy/hints" diff --git a/lib/generators/alchemy/essence/essence_generator.rb b/lib/generators/alchemy/essence/essence_generator.rb deleted file mode 100644 index 8946856ba8..0000000000 --- a/lib/generators/alchemy/essence/essence_generator.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true -require "rails" - -module Alchemy - module Generators - class EssenceGenerator < ::Rails::Generators::Base - desc "This generator generates an Alchemy essence for you." - argument :essence_name, banner: "YourEssenceName" - source_root File.expand_path("templates", __dir__) - - def init - @essence_name = essence_name.underscore - @essence_view_path = "app/views/alchemy/essences" - end - - def create_model - invoke("model", [@essence_name]) - end - - def act_as_essence - essence_class_file = "app/models/#{@essence_name}.rb" - essence_class = @essence_name.classify - inject_into_class essence_class_file, essence_class, <<~CLASSMETHOD - acts_as_essence( - # Your options: - # - # ingredient_column: [String or Symbol] - Specifies the column name you use for storing the content in the database. (Default :body) - # validate_column: [String or Symbol] - Which column should be validated. (Default: ingredient_column) - # preview_text_column: [String or Symbol] - Specifies the column for the preview_text method. (Default: ingredient_column) - # preview_text_method: [String or Symbol] - A method called on ingredient to get the preview text. (Default: ingredient_column) - ) - CLASSMETHOD - end - - def copy_templates - essence_name = @essence_name.classify.demodulize.underscore - @essence_editor_local = "#{essence_name}_editor" - template "view.html.erb", "#{@essence_view_path}/_#{essence_name}_view.html.erb" - template "editor.html.erb", "#{@essence_view_path}/_#{essence_name}_editor.html.erb" - end - - def show_todo - say "\nPlease open the generated migration file and add your columns to your table." - say "Then run 'rake db:migrate' to update your database." - say "Also check the generated view files and alter them to fit your needs." - end - end - end -end diff --git a/lib/generators/alchemy/essence/templates/editor.html.erb b/lib/generators/alchemy/essence/templates/editor.html.erb deleted file mode 100644 index cbdcfd85a8..0000000000 --- a/lib/generators/alchemy/essence/templates/editor.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -<%%# - Available locals: - * <%= @essence_editor_local %> - A Alchemy::ContentEditor instance - - Please consult Alchemy::Content.rb docs for further methods on the content object -%> -<%%= content_tag :div, - id: <%= @essence_editor_local %>.dom_id, - class: <%= @essence_editor_local %>.css_classes, - data: <%= @essence_editor_local %>.data_attributes do %> - <%%= content_label(<%= @essence_editor_local %>) %> - <%%= text_field_tag( - <%= @essence_editor_local %>.form_field_name, - <%= @essence_editor_local %>.ingredient, - id: <%= @essence_editor_local %>.form_field_id - ) %> -<%% end %> diff --git a/lib/generators/alchemy/essence/templates/view.html.erb b/lib/generators/alchemy/essence/templates/view.html.erb deleted file mode 100644 index caea7e7a38..0000000000 --- a/lib/generators/alchemy/essence/templates/view.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -<%%# The content object holds the essence %> -<%%= content.ingredient %> diff --git a/spec/controllers/alchemy/admin/elements_controller_spec.rb b/spec/controllers/alchemy/admin/elements_controller_spec.rb index c607968874..9a10f43737 100644 --- a/spec/controllers/alchemy/admin/elements_controller_spec.rb +++ b/spec/controllers/alchemy/admin/elements_controller_spec.rb @@ -206,41 +206,6 @@ module Alchemy expect(Element).to receive(:find).at_least(:once).and_return(element) end - context "with element having contents" do - subject do - put :update, params: { id: element.id, element: element_params, contents: contents_params }.compact, xhr: true - end - - let(:element) { create(:alchemy_element, :with_contents) } - let(:content) { element.contents.first } - let(:element_params) { { tag_list: "Tag 1", public: false } } - let(:contents_params) { { content.id => { ingredient: "Title" } } } - - it "updates all contents in element" do - expect { subject }.to change { content.reload.ingredient }.to("Title") - end - - it "updates the element" do - expect { subject }.to change { element.tag_list }.to(["Tag 1"]) - end - - context "failed validations" do - it "displays validation failed notice" do - expect(element).to receive(:update_contents).and_return(false) - subject - expect(assigns(:element_validated)).to be_falsey - end - end - - context "with element not taggable" do - let(:element_params) { nil } - - it "updates the element" do - expect { subject }.to_not raise_error - end - end - end - context "with element having ingredients" do subject do put :update, params: { id: element.id, element: element_params }, xhr: true diff --git a/spec/controllers/alchemy/admin/essence_audios_controller_spec.rb b/spec/controllers/alchemy/admin/essence_audios_controller_spec.rb deleted file mode 100644 index d191fd6c29..0000000000 --- a/spec/controllers/alchemy/admin/essence_audios_controller_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Alchemy::Admin::EssenceAudiosController do - routes { Alchemy::Engine.routes } - - before do - authorize_user(:as_author) - end - - let(:essence_audio) { mock_model("Alchemy::EssenceAudio", attachment: nil, content: content) } - let(:content) { mock_model("Alchemy::Content") } - let(:attachment) { mock_model("Alchemy::Attachment") } - - describe "#edit" do - before do - expect(Alchemy::EssenceAudio).to receive(:find).with(essence_audio.id.to_s) { essence_audio } - end - - it "assigns @essence_audio with the Alchemy::EssenceAudio found by id" do - get :edit, params: { id: essence_audio.id } - expect(assigns(:essence_audio)).to eq(essence_audio) - end - end - - describe "#update" do - let(:essence_audio) { create(:alchemy_essence_audio) } - - let(:params) do - { - id: essence_audio.id, - essence_audio: { - autoplay: false, - controls: true, - loop: false, - muted: true, - }, - } - end - - before do - expect(Alchemy::EssenceAudio).to receive(:find) { essence_audio } - end - - it "should update the attributes of essence_audio" do - put :update, params: params, xhr: true - expect(essence_audio.autoplay).to eq false - expect(essence_audio.controls).to eq true - expect(essence_audio.loop).to eq false - expect(essence_audio.muted).to eq true - end - end -end diff --git a/spec/controllers/alchemy/admin/essence_files_controller_spec.rb b/spec/controllers/alchemy/admin/essence_files_controller_spec.rb deleted file mode 100644 index 5123a48baa..0000000000 --- a/spec/controllers/alchemy/admin/essence_files_controller_spec.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe Admin::EssenceFilesController do - routes { Alchemy::Engine.routes } - - before do - authorize_user(:as_admin) - end - - let(:essence_file) { mock_model("EssenceFile", :attachment= => nil, content: content) } - let(:content) { mock_model("Content") } - let(:attachment) { mock_model("Attachment") } - - describe "#edit" do - before do - expect(EssenceFile).to receive(:find).with(essence_file.id.to_s) { essence_file } - end - - it "assigns @essence_file with the EssenceFile found by id" do - get :edit, params: { id: essence_file.id } - expect(assigns(:essence_file)).to eq(essence_file) - end - - it "should assign @content with essence_file's content" do - get :edit, params: { id: essence_file.id } - expect(assigns(:content)).to eq(content) - end - end - - describe "#update" do - let(:essence_file) { create(:alchemy_essence_file) } - - let(:params) do - { - id: essence_file.id, - essence_file: { - title: "new title", - css_class: "left", - link_text: "Download this file", - }, - } - end - - before do - expect(EssenceFile).to receive(:find) { essence_file } - end - - it "should update the attributes of essence_file" do - put :update, params: params, xhr: true - expect(essence_file.title).to eq "new title" - expect(essence_file.css_class).to eq "left" - expect(essence_file.link_text).to eq "Download this file" - end - end - end -end diff --git a/spec/controllers/alchemy/admin/essence_pictures_controller_spec.rb b/spec/controllers/alchemy/admin/essence_pictures_controller_spec.rb deleted file mode 100644 index 18ac49faf6..0000000000 --- a/spec/controllers/alchemy/admin/essence_pictures_controller_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe Admin::EssencePicturesController do - routes { Alchemy::Engine.routes } - - before { authorize_user(:as_admin) } - - let(:essence) { EssencePicture.new(content: content, picture: picture) } - let(:content) { Content.new } - let(:picture) { Picture.new } - - describe "#edit" do - before do - expect(EssencePicture).to receive(:find).and_return(essence) - expect(Content).to receive(:find).and_return(content) - end - - it "should assign @essence_picture and @content instance variables" do - post :edit, params: { id: 1, content_id: 1 } - expect(assigns(:essence_picture)).to be_a(EssencePicture) - expect(assigns(:content)).to be_a(Content) - end - end - - it_behaves_like "having crop action", model_class: Alchemy::EssencePicture do - let(:croppable_resource) { essence } - end - - describe "#update" do - before do - expect(EssencePicture).to receive(:find).and_return(essence) - expect(Content).to receive(:find).and_return(content) - end - - let(:attributes) do - { - render_size: "1x1", - alt_tag: "Alt Tag", - caption: "Caption", - css_class: "CSS Class", - title: "Title", - } - end - - it "updates the essence attributes" do - expect(essence).to receive(:update).and_return(true) - put :update, params: { id: 1, essence_picture: attributes }, xhr: true - end - - it "saves the cropping mask" do - expect(essence).to receive(:update).and_return(true) - put :update, params: { - id: 1, - essence_picture: { - render_size: "1x1", - crop_from: "0x0", - crop_size: "100x100", - }, - }, xhr: true - end - end - end -end diff --git a/spec/controllers/alchemy/admin/essence_videos_controller_spec.rb b/spec/controllers/alchemy/admin/essence_videos_controller_spec.rb deleted file mode 100644 index c32299c53e..0000000000 --- a/spec/controllers/alchemy/admin/essence_videos_controller_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Alchemy::Admin::EssenceVideosController do - routes { Alchemy::Engine.routes } - - before do - authorize_user(:as_author) - end - - let(:essence_video) { mock_model("Alchemy::EssenceVideo", attachment: nil, content: content) } - let(:content) { mock_model("Alchemy::Content") } - let(:attachment) { mock_model("Alchemy::Attachment") } - - describe "#edit" do - before do - expect(Alchemy::EssenceVideo).to receive(:find).with(essence_video.id.to_s) { essence_video } - end - - it "assigns @essence_video with the Alchemy::EssenceVideo found by id" do - get :edit, params: { id: essence_video.id } - expect(assigns(:essence_video)).to eq(essence_video) - end - end - - describe "#update" do - let(:essence_video) { create(:alchemy_essence_video) } - - let(:params) do - { - id: essence_video.id, - essence_video: { - width: "200", - height: "150", - autoplay: false, - controls: true, - loop: false, - muted: true, - preload: "auto", - }, - } - end - - before do - expect(Alchemy::EssenceVideo).to receive(:find) { essence_video } - end - - it "should update the attributes of essence_video" do - put :update, params: params, xhr: true - expect(essence_video.width).to eq "200" - expect(essence_video.height).to eq "150" - expect(essence_video.autoplay).to eq false - expect(essence_video.controls).to eq true - expect(essence_video.loop).to eq false - expect(essence_video.muted).to eq true - expect(essence_video.preload).to eq "auto" - end - end -end diff --git a/spec/controllers/alchemy/admin/pictures_controller_spec.rb b/spec/controllers/alchemy/admin/pictures_controller_spec.rb index 785d98b399..422ccbe7d6 100644 --- a/spec/controllers/alchemy/admin/pictures_controller_spec.rb +++ b/spec/controllers/alchemy/admin/pictures_controller_spec.rb @@ -168,12 +168,11 @@ module Alchemy context "with assignments" do let!(:page) { create(:alchemy_page) } let!(:element) { create(:alchemy_element, page: page) } - let!(:content) { create(:alchemy_content, element: element) } - let!(:essence) { create(:alchemy_essence_picture, content: content, picture: picture) } + let!(:ingredient) { create(:alchemy_ingredient_picture, element: element, related_object: picture) } - it "assigns all essence pictures having an assignment to @assignments" do + it "assigns all picture ingredients having an assignment to @assignments" do get :show, params: { id: picture.id } - expect(assigns(:assignments)).to eq([essence]) + expect(assigns(:assignments)).to eq([ingredient]) end end diff --git a/spec/controllers/alchemy/api/contents_controller_spec.rb b/spec/controllers/alchemy/api/contents_controller_spec.rb deleted file mode 100644 index d4fba343aa..0000000000 --- a/spec/controllers/alchemy/api/contents_controller_spec.rb +++ /dev/null @@ -1,143 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe Api::ContentsController do - routes { Alchemy::Engine.routes } - - describe "#index" do - let!(:page) { create(:alchemy_page) } - let!(:element) { create(:alchemy_element, page: page) } - let!(:content) { create(:alchemy_content, element: element) } - - it "returns all public contents as json objects" do - get :index, params: {format: :json} - - expect(response.status).to eq(200) - expect(response.media_type).to eq("application/json") - - result = JSON.parse(response.body) - - expect(result).to have_key("contents") - expect(result["contents"].size).to eq(Alchemy::Content.count) - end - - context "with element_id" do - let!(:other_element) { create(:alchemy_element, page: page) } - let!(:other_content) { create(:alchemy_content, element: other_element) } - - it "returns only contents from this element" do - get :index, params: {element_id: other_element.id, format: :json} - - expect(response.status).to eq(200) - expect(response.media_type).to eq("application/json") - - result = JSON.parse(response.body) - - expect(result).to have_key("contents") - expect(result["contents"].size).to eq(1) - expect(result["contents"][0]["element_id"]).to eq(other_element.id) - end - end - - context "with empty element_id" do - it "returns all contents" do - get :index, params: {element_id: element.id, format: :json} - - expect(response.status).to eq(200) - expect(response.media_type).to eq("application/json") - - result = JSON.parse(response.body) - - expect(result).to have_key("contents") - expect(result["contents"].size).to eq(Alchemy::Content.count) - end - end - - context "as author" do - before do - authorize_user(build(:alchemy_dummy_user, :as_author)) - end - - it "returns all contents" do - get :index, params: {format: :json} - - expect(response.status).to eq(200) - expect(response.media_type).to eq("application/json") - - result = JSON.parse(response.body) - - expect(result).to have_key("contents") - expect(result["contents"].size).to eq(Alchemy::Content.count) - end - end - end - - describe "#show" do - context "with no other params given" do - let(:page) { create(:alchemy_page) } - let(:element) { create(:alchemy_element, page: page) } - let(:content) { create(:alchemy_content, element: element) } - - it "returns content as json" do - get :show, params: {id: content.id, format: :json} - - expect(response.status).to eq(200) - expect(response.media_type).to eq("application/json") - - result = JSON.parse(response.body) - - expect(result["id"]).to eq(content.id) - end - - context "requesting an restricted content" do - let(:page) { create(:alchemy_page, restricted: true) } - - it "responds with 403" do - get :show, params: {id: content.id, format: :json} - - expect(response.media_type).to eq("application/json") - expect(response.status).to eq(403) - - result = JSON.parse(response.body) - - expect(result).to have_key("error") - expect(result["error"]).to eq("Not authorized") - end - end - end - - context "with element_id and name params given" do - let!(:page) { create(:alchemy_page) } - let!(:element) { create(:alchemy_element, page: page) } - let!(:content) { create(:alchemy_content, element: element) } - - it "returns the named content from element with given id." do - get :show, params: {element_id: element.id, name: content.name, format: :json} - - expect(response.status).to eq(200) - expect(response.media_type).to eq("application/json") - - result = JSON.parse(response.body) - - expect(result["id"]).to eq(content.id) - end - end - - context "with empty element_id or name param" do - it "returns 404 error." do - get :show, params: {element_id: "", name: "", format: :json} - - expect(response.status).to eq(404) - expect(response.media_type).to eq("application/json") - - result = JSON.parse(response.body) - - expect(result).to have_key("error") - expect(result["error"]).to eq("Record not found") - end - end - end - end -end diff --git a/spec/controllers/alchemy/pages_controller_spec.rb b/spec/controllers/alchemy/pages_controller_spec.rb index 14bbe4210b..993bc68578 100644 --- a/spec/controllers/alchemy/pages_controller_spec.rb +++ b/spec/controllers/alchemy/pages_controller_spec.rb @@ -178,7 +178,7 @@ module Alchemy before do allow(Alchemy.user_class).to receive(:admins).and_return(OpenStruct.new(count: 1)) - product.elements.find_by_name("article").contents.essence_texts.first.essence.update_column(:body, "screwdriver") + product.elements.find_by_name("article").ingredients.texts.first.update_column(:value, "screwdriver") end context "with correct levelnames in params" do @@ -236,8 +236,8 @@ module Alchemy let!(:english_page) { create(:alchemy_page, :public, language: default_language, name: "same-name") } before do - # Set a text in an essence rendered on the page so we can match against that - klingon_page.essence_texts.first.update_column(:body, "klingon page") + # Set a text in an ingredient rendered on the page so we can match against that + klingon_page.ingredients.texts.first.update_column(:value, "klingon page") end it "renders the page related to its language" do diff --git a/spec/decorators/alchemy/content_editor_spec.rb b/spec/decorators/alchemy/content_editor_spec.rb deleted file mode 100644 index c177fd9429..0000000000 --- a/spec/decorators/alchemy/content_editor_spec.rb +++ /dev/null @@ -1,199 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Alchemy::ContentEditor do - let(:essence) { Alchemy::EssenceText.new } - let(:content) { Alchemy::Content.new(id: 1, essence: essence) } - let(:content_editor) { described_class.new(content) } - - describe "#content" do - it "returns content object" do - expect(content_editor.content).to eq(content) - end - end - - describe "#css_classes" do - subject { content_editor.css_classes } - - it "includes content_editor class" do - is_expected.to include("content_editor") - end - - it "includes essence partial class" do - is_expected.to include(content_editor.essence_partial_name) - end - - context "when deprecated" do - before do - expect(content).to receive(:deprecated?) { true } - end - - it "includes deprecated" do - is_expected.to include("deprecated") - end - end - end - - describe "#data_attributes" do - it "includes content_id" do - expect(content_editor.data_attributes[:content_id]).to eq(content_editor.id) - end - - it "includes content_name" do - expect(content_editor.data_attributes[:content_name]).to eq(content_editor.name) - end - end - - describe "#to_partial_path" do - subject { content_editor.to_partial_path } - - it "returns the editor partial path" do - is_expected.to eq("alchemy/essences/essence_text_editor") - end - end - - describe "#form_field_name" do - it "returns a name value for form fields with ingredient as default" do - expect(content_editor.form_field_name).to eq("contents[1][ingredient]") - end - - context "with a essence column given" do - it "returns a name value for form fields for that column" do - expect(content_editor.form_field_name(:link_title)).to eq("contents[1][link_title]") - end - end - end - - describe "#form_field_id" do - it "returns a id value for form fields with ingredient as default" do - expect(content_editor.form_field_id).to eq("contents_1_ingredient") - end - - context "with a essence column given" do - it "returns a id value for form fields for that column" do - expect(content_editor.form_field_id(:link_title)).to eq("contents_1_link_title") - end - end - end - - describe "#respond_to?(:to_model)" do - subject { content_editor.respond_to?(:to_model) } - - it { is_expected.to be(false) } - end - - describe "#has_warnings?" do - subject { content_editor.has_warnings? } - - context "when content is not deprecated" do - let(:content) { build(:alchemy_content) } - - it { is_expected.to be(false) } - end - - context "when content is deprecated" do - let(:content) do - mock_model("Content", definition: { deprecated: true }, deprecated?: true) - end - - it { is_expected.to be(true) } - end - - context "when content is missing its definition" do - let(:content) do - mock_model("Content", definition: {}) - end - - it { is_expected.to be(true) } - end - end - - describe "#warnings" do - subject { content_editor.warnings } - - context "when content has no warnings" do - let(:content) { build(:alchemy_content) } - - it { is_expected.to be_nil } - end - - context "when content is missing its definition" do - let(:content) do - mock_model("Content", name: "foo", definition: {}) - end - - it { is_expected.to eq Alchemy.t(:content_definition_missing) } - - it "logs a warning" do - expect(Alchemy::Logger).to receive(:warn) - subject - end - end - - context "when content is deprecated" do - let(:content) do - mock_model("Content", - name: "foo", - definition: { "name" => "foo", "deprecated" => "Deprecated" }, - deprecated?: true) - end - - it "returns a deprecation notice" do - is_expected.to eq("Deprecated") - end - end - end - - describe "#deprecation_notice" do - subject { content_editor.deprecation_notice } - - context "when content is not deprecated" do - let(:content) { build(:alchemy_content) } - - it { is_expected.to be_nil } - end - - context "when content is deprecated" do - let(:element) { build(:alchemy_element, name: "all_you_can_eat") } - let(:content) { build(:alchemy_content, name: "essence_html", element: element) } - - context "with custom content translation" do - it { is_expected.to eq("Old content is deprecated") } - end - - context "without custom content translation" do - let(:content) { build(:alchemy_content, name: "old_too", element: element) } - - before do - allow(content).to receive(:definition) do - { - "name" => "old_too", - "deprecated" => true, - } - end - end - - it do - is_expected.to eq( - "WARNING! This content is deprecated and will be removed soon. " \ - "Please do not use it anymore." - ) - end - end - - context "with String as deprecation" do - before do - allow(content).to receive(:definition) do - { - "name" => "old", - "deprecated" => "Foo baz widget", - } - end - end - - it { is_expected.to eq("Foo baz widget") } - end - end - end -end diff --git a/spec/decorators/alchemy/element_editor_spec.rb b/spec/decorators/alchemy/element_editor_spec.rb index 49e0290cdf..e58d6c8ac2 100644 --- a/spec/decorators/alchemy/element_editor_spec.rb +++ b/spec/decorators/alchemy/element_editor_spec.rb @@ -12,50 +12,12 @@ end end - describe "#contents" do - let(:element) { create(:alchemy_element, :with_contents, name: "headline") } - - subject(:contents) { element_editor.contents } - - it "returns a ContentEditor instance for each content defined" do - aggregate_failures do - contents.each do |content| - expect(content).to be_an(Alchemy::ContentEditor) - end - end - end - - context "with a content defined but not existing yet" do - before do - expect(element).to receive(:definition).at_least(:once) do - { - name: "headline", - contents: [ - { - name: "headline", - type: "EssenceText", - }, - { - name: "foo", - type: "EssenceText", - }, - ], - }.with_indifferent_access - end - end - - it "creates the missing content" do - expect { subject }.to change { element.contents.count }.by(1) - end - end - end - describe "#ingredients" do let(:element) { create(:alchemy_element, :with_ingredients) } subject(:ingredients) { element_editor.ingredients } - it "returns a ContentEditor instance for each ingredient defined" do + it "returns a IngredientEditor instance for each ingredient defined" do aggregate_failures do ingredients.each do |ingredient| expect(ingredient).to be_an(Alchemy::IngredientEditor) @@ -141,20 +103,20 @@ it { is_expected.to include("not-taggable") } end - context "with element having content_definitions" do + context "with element having ingredient_definitions" do before do - allow(element).to receive(:content_definitions) { [1] } + allow(element).to receive(:ingredient_definitions) { [1] } end - it { is_expected.to include("with-contents") } + it { is_expected.to include("with-ingredients") } end - context "with element not having content_definitions" do + context "with element not having ingredient_definitions" do before do - allow(element).to receive(:content_definitions) { [] } + allow(element).to receive(:ingredient_definitions) { [] } end - it { is_expected.to include("without-contents") } + it { is_expected.to include("without-ingredients") } end context "with element having nestable_elements" do @@ -194,14 +156,14 @@ context "for expanded element" do before { allow(element).to receive(:folded?) { false } } - context "and element having contents defined" do - before { allow(element).to receive(:content_definitions) { [1] } } + context "and element having ingredients defined" do + before { allow(element).to receive(:ingredient_definitions) { [1] } } it { is_expected.to eq(true) } end - context "and element having no contents defined" do - before { allow(element).to receive(:content_definitions) { [] } } + context "and element having no ingredients defined" do + before { allow(element).to receive(:ingredient_definitions) { [] } } context "and element beeing taggable" do before { allow(element).to receive(:taggable?) { true } } @@ -214,18 +176,6 @@ it { is_expected.to eq(false) } end - - context "but element has ingredients defined" do - before { - expect(element).to receive(:ingredient_definitions) { - [{ - role: "headline", type: "Headline", - }] - } - } - - it { is_expected.to eq(true) } - end end end end diff --git a/spec/dummy/app/models/dummy_model.rb b/spec/dummy/app/models/dummy_model.rb deleted file mode 100644 index 7a369c9ff7..0000000000 --- a/spec/dummy/app/models/dummy_model.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -class DummyModel < ActiveRecord::Base - acts_as_essence ingredient_column: "data" -end diff --git a/spec/dummy/config/alchemy/elements.yml b/spec/dummy/config/alchemy/elements.yml index e8ec8ddca6..bbeaaa6bfd 100644 --- a/spec/dummy/config/alchemy/elements.yml +++ b/spec/dummy/config/alchemy/elements.yml @@ -1,125 +1,125 @@ - name: header unique: true - contents: - - name: image - type: EssencePicture + ingredients: + - role: image + type: Picture - name: headline - contents: - - name: headline - type: EssenceHeadline + ingredients: + - role: headline + type: Headline - name: article taggable: true - contents: - - name: intro - type: EssenceText - - name: headline - type: EssenceText + ingredients: + - role: intro + type: Text + - role: headline + type: Text settings: linkable: true - - name: image - type: EssencePicture + - role: image + type: Picture settings: size: 450x300 crop: true - - name: text - type: EssenceRichtext + - role: text + type: Richtext - name: text - contents: - - name: text - type: EssenceRichtext + ingredients: + - role: text + type: Richtext settings: sanitizer: attributes: [href, target] tags: [p, ol, ul, ul, li, em, strong] - name: search - contents: [] + ingredients: [] - name: news - contents: - - name: date - type: EssenceDate - - name: news_headline - type: EssenceText - - name: body - type: EssenceRichtext + ingredients: + - role: date + type: Datetime + - role: news_headline + type: Text + - role: body + type: Richtext - name: download - contents: - - name: file - type: EssenceFile + ingredients: + - role: file + type: File - name: bild - contents: - - name: image - type: EssencePicture + ingredients: + - role: image + type: Picture - name: contactform unique: true - contents: - - name: mail_from - type: EssenceText + ingredients: + - role: mail_from + type: Text validate: - presence - - name: mail_to - type: EssenceText + - role: mail_to + type: Text validate: - presence - - name: subject - type: EssenceText + - role: subject + type: Text as_element_title: true validate: - presence - - name: success_page - type: EssencePage + - role: success_page + type: Page validate: - presence - name: all_you_can_eat hint: true taggable: true - contents: - - name: essence_text - type: EssenceText + ingredients: + - role: text + type: Text hint: true - - name: essence_picture - type: EssencePicture + - role: picture + type: Picture hint: true settings: size: 1200x480 crop: true - - name: essence_richtext - type: EssenceRichtext + - role: richtext + type: Richtext hint: true - - name: essence_select - type: EssenceSelect + - role: select + type: Select hint: true settings: select_values: [A, B, C] - - name: essence_boolean - type: EssenceBoolean + - role: boolean + type: Boolean hint: true - - name: essence_date - type: EssenceDate + - role: date + type: Datetime hint: true - - name: essence_audio - type: EssenceAudio + - role: audio + type: Audio hint: true - - name: essence_file - type: EssenceFile + - role: file + type: File hint: true - - name: essence_video - type: EssenceVideo + - role: video + type: Video hint: true - - name: essence_html - type: EssenceHtml + - role: html + type: Html hint: true deprecated: true - - name: essence_link - type: EssenceLink + - role: link + type: Link hint: true - name: all_you_can_eat_ingredients @@ -189,17 +189,17 @@ hint: true - name: <%= 'erb_' + 'element' %> - contents: - - name: text - type: EssenceRichtext + ingredients: + - role: text + type: Richtext - name: slide compact: true - contents: - - name: picture - type: EssencePicture - - name: caption - type: EssenceText + ingredients: + - role: picture + type: Picture + - role: caption + type: Text as_element_title: true - name: slider @@ -214,9 +214,9 @@ - name: gallery_picture compact: true - contents: - - name: picture - type: EssencePicture + ingredients: + - role: picture + type: Picture settings: size: 160x120 crop: true @@ -224,9 +224,9 @@ - name: right_column fixed: true unique: true - contents: - - name: title - type: EssenceText + ingredients: + - role: title + type: Text nestable_elements: [search, text] - name: left_column @@ -240,17 +240,17 @@ nestable_elements: [text] - name: menu - contents: - - name: menu - type: EssenceNode + ingredients: + - role: menu + type: Node - name: old deprecated: true - contents: - - name: title - type: EssenceText - - name: text - type: EssenceRichtext + ingredients: + - role: title + type: Text + - role: text + type: Richtext - name: element_with_ingredients ingredients: @@ -280,20 +280,3 @@ - role: key_words type: Text group: details - -- name: element_with_content_groups - contents: - - name: title - type: EssenceText - - name: description - type: EssenceRichtext - group: details - - name: width - type: EssenceText - group: size - - name: height - type: EssenceText - group: size - - name: key_words - type: EssenceText - group: details diff --git a/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb b/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb deleted file mode 100644 index 0d870e645d..0000000000 --- a/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class CreateDummyModel < ActiveRecord::Migration[4.2] - def change - create_table :dummy_models do |t| - t.string :data - end - end -end diff --git a/spec/dummy/db/migrate/20200226213334_alchemy_four_point_four.rb b/spec/dummy/db/migrate/20200226213334_alchemy_four_point_four.rb deleted file mode 120000 index 7c5bd382df..0000000000 --- a/spec/dummy/db/migrate/20200226213334_alchemy_four_point_four.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20200226213334_alchemy_four_point_four.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20200423073425_create_alchemy_essence_nodes.rb b/spec/dummy/db/migrate/20200423073425_create_alchemy_essence_nodes.rb deleted file mode 120000 index 7c19075432..0000000000 --- a/spec/dummy/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20200423073425_create_alchemy_essence_nodes.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20200504210159_remove_site_id_from_nodes.rb b/spec/dummy/db/migrate/20200504210159_remove_site_id_from_nodes.rb deleted file mode 120000 index 6c80fe7846..0000000000 --- a/spec/dummy/db/migrate/20200504210159_remove_site_id_from_nodes.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20200504210159_remove_site_id_from_nodes.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb b/spec/dummy/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb deleted file mode 120000 index b13520df09..0000000000 --- a/spec/dummy/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb b/spec/dummy/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb deleted file mode 120000 index 11efc9ef63..0000000000 --- a/spec/dummy/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20200514091507_make_page_layoutpage_null_false.rb b/spec/dummy/db/migrate/20200514091507_make_page_layoutpage_null_false.rb deleted file mode 120000 index 4d55e7a290..0000000000 --- a/spec/dummy/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20200514091507_make_page_layoutpage_null_false.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb b/spec/dummy/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb deleted file mode 120000 index 3e5342b228..0000000000 --- a/spec/dummy/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb b/spec/dummy/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb deleted file mode 120000 index 9e9ff2ed7c..0000000000 --- a/spec/dummy/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20200617110713_create_alchemy_picture_thumbs.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20200907111332_remove_tri_state_booleans.rb b/spec/dummy/db/migrate/20200907111332_remove_tri_state_booleans.rb deleted file mode 120000 index 063e53e65f..0000000000 --- a/spec/dummy/db/migrate/20200907111332_remove_tri_state_booleans.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20200907111332_remove_tri_state_booleans.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20201207131309_create_page_versions.rb b/spec/dummy/db/migrate/20201207131309_create_page_versions.rb deleted file mode 120000 index 0377235c35..0000000000 --- a/spec/dummy/db/migrate/20201207131309_create_page_versions.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20201207131309_create_page_versions.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb b/spec/dummy/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb deleted file mode 120000 index 0a3f03a90d..0000000000 --- a/spec/dummy/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb b/spec/dummy/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb deleted file mode 120000 index 5945aff82e..0000000000 --- a/spec/dummy/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb b/spec/dummy/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb deleted file mode 120000 index a6812a41e3..0000000000 --- a/spec/dummy/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20210406093436_add_alchemy_essence_headlines.rb b/spec/dummy/db/migrate/20210406093436_add_alchemy_essence_headlines.rb deleted file mode 120000 index cd30968cd8..0000000000 --- a/spec/dummy/db/migrate/20210406093436_add_alchemy_essence_headlines.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20210406093436_add_alchemy_essence_headlines.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20210506135919_create_essence_audios.rb b/spec/dummy/db/migrate/20210506135919_create_essence_audios.rb deleted file mode 120000 index adcf4f1412..0000000000 --- a/spec/dummy/db/migrate/20210506135919_create_essence_audios.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20210506135919_create_essence_audios.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20210506140258_create_essence_videos.rb b/spec/dummy/db/migrate/20210506140258_create_essence_videos.rb deleted file mode 120000 index 3e82a38f4c..0000000000 --- a/spec/dummy/db/migrate/20210506140258_create_essence_videos.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20210506140258_create_essence_videos.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20210508091432_create_alchemy_ingredients.rb b/spec/dummy/db/migrate/20210508091432_create_alchemy_ingredients.rb deleted file mode 120000 index e94fcb1c52..0000000000 --- a/spec/dummy/db/migrate/20210508091432_create_alchemy_ingredients.rb +++ /dev/null @@ -1 +0,0 @@ -../../../../db/migrate/20210508091432_create_alchemy_ingredients.rb \ No newline at end of file diff --git a/spec/dummy/db/migrate/20220831084620_add_playsinline_to_alchemy_essence_videos.alchemy.rb b/spec/dummy/db/migrate/20220831084620_add_playsinline_to_alchemy_essence_videos.alchemy.rb deleted file mode 100644 index b7dc1075fc..0000000000 --- a/spec/dummy/db/migrate/20220831084620_add_playsinline_to_alchemy_essence_videos.alchemy.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -# This migration comes from alchemy (originally 20220622130905) -class AddPlaysinlineToAlchemyEssenceVideos < ActiveRecord::Migration[6.0] - def change - return if column_exists?(:alchemy_essence_videos, :playsinline) - - add_column :alchemy_essence_videos, :playsinline, :boolean, default: false, null: false - end -end diff --git a/spec/dummy/db/migrate/20191129235819_gutentag_tables.gutentag.rb b/spec/dummy/db/migrate/20230119091654_gutentag_tables.gutentag.rb similarity index 78% rename from spec/dummy/db/migrate/20191129235819_gutentag_tables.gutentag.rb rename to spec/dummy/db/migrate/20230119091654_gutentag_tables.gutentag.rb index 4dbea15c75..3b444996b8 100644 --- a/spec/dummy/db/migrate/20191129235819_gutentag_tables.gutentag.rb +++ b/spec/dummy/db/migrate/20230119091654_gutentag_tables.gutentag.rb @@ -1,13 +1,8 @@ # frozen_string_literal: true -# This migration comes from gutentag (originally 1) -superclass = ActiveRecord::VERSION::MAJOR < 5 ? - ActiveRecord::Migration : ActiveRecord::Migration[4.2] -class GutentagTables < superclass +# This migration comes from gutentag (originally 1) +class GutentagTables < ActiveRecord::Migration[4.2] def up - # inserted by Alchemy CMS upgrader - return if table_exists?(:gutentag_taggings) - create_table :gutentag_taggings do |t| t.integer :tag_id, :null => false t.integer :taggable_id, :null => false diff --git a/spec/dummy/db/migrate/20191129235820_gutentag_cache_counter.gutentag.rb b/spec/dummy/db/migrate/20230119091655_gutentag_cache_counter.gutentag.rb similarity index 64% rename from spec/dummy/db/migrate/20191129235820_gutentag_cache_counter.gutentag.rb rename to spec/dummy/db/migrate/20230119091655_gutentag_cache_counter.gutentag.rb index cc093b257f..c00edd42da 100644 --- a/spec/dummy/db/migrate/20191129235820_gutentag_cache_counter.gutentag.rb +++ b/spec/dummy/db/migrate/20230119091655_gutentag_cache_counter.gutentag.rb @@ -1,13 +1,8 @@ # frozen_string_literal: true -# This migration comes from gutentag (originally 2) -superclass = ActiveRecord::VERSION::MAJOR < 5 ? - ActiveRecord::Migration : ActiveRecord::Migration[4.2] -class GutentagCacheCounter < superclass +# This migration comes from gutentag (originally 2) +class GutentagCacheCounter < ActiveRecord::Migration[4.2] def up - # inserted by Alchemy CMS upgrader - return if column_exists?(:gutentag_tags, :taggings_count) - add_column :gutentag_tags, :taggings_count, :integer, :default => 0 add_index :gutentag_tags, :taggings_count diff --git a/spec/dummy/db/migrate/20191129235821_no_null_counters.gutentag.rb b/spec/dummy/db/migrate/20230119091656_no_null_counters.gutentag.rb similarity index 70% rename from spec/dummy/db/migrate/20191129235821_no_null_counters.gutentag.rb rename to spec/dummy/db/migrate/20230119091656_no_null_counters.gutentag.rb index 8503167f75..17939cae84 100644 --- a/spec/dummy/db/migrate/20191129235821_no_null_counters.gutentag.rb +++ b/spec/dummy/db/migrate/20230119091656_no_null_counters.gutentag.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true -# This migration comes from gutentag (originally 3) -superclass = ActiveRecord::VERSION::MAJOR < 5 ? - ActiveRecord::Migration : ActiveRecord::Migration[4.2] -class NoNullCounters < superclass +# This migration comes from gutentag (originally 3) +class NoNullCounters < ActiveRecord::Migration[4.2] def up change_column :gutentag_tags, :taggings_count, :integer, :default => 0, diff --git a/spec/dummy/db/migrate/20230119091717_alchemy_four_point_four.alchemy.rb b/spec/dummy/db/migrate/20230119091717_alchemy_four_point_four.alchemy.rb new file mode 100644 index 0000000000..1c76b95a65 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091717_alchemy_four_point_four.alchemy.rb @@ -0,0 +1,201 @@ +# frozen_string_literal: true + +# This migration comes from alchemy (originally 20200226213334) +class AlchemyFourPointFour < ActiveRecord::Migration[6.0] + def up + unless table_exists?("alchemy_attachments") + create_table "alchemy_attachments" do |t| + t.string "name" + t.string "file_name" + t.string "file_mime_type" + t.integer "file_size" + t.references "creator" + t.references "updater" + t.timestamps + t.string "file_uid" + t.index ["file_uid"], name: "index_alchemy_attachments_on_file_uid" + end + end + + unless table_exists?("alchemy_elements") + create_table "alchemy_elements" do |t| + t.string "name" + t.integer "position" + t.references "page", null: false, index: false + t.boolean "public", default: true + t.boolean "folded", default: false + t.boolean "unique", default: false + t.timestamps + t.references "creator" + t.references "updater" + t.references "parent_element", index: false + t.boolean "fixed", default: false, null: false + t.index ["fixed"], name: "index_alchemy_elements_on_fixed" + t.index ["page_id", "parent_element_id"], name: "index_alchemy_elements_on_page_id_and_parent_element_id" + t.index ["page_id", "position"], name: "index_elements_on_page_id_and_position" + end + end + + unless table_exists?("alchemy_elements_alchemy_pages") + create_table "alchemy_elements_alchemy_pages", id: false do |t| + t.references "element" + t.references "page" + end + end + + unless table_exists?("alchemy_folded_pages") + create_table "alchemy_folded_pages" do |t| + t.references "page", null: false, index: false + t.references "user", null: false, index: false + t.boolean "folded", default: false + t.index ["page_id", "user_id"], name: "index_alchemy_folded_pages_on_page_id_and_user_id", unique: true + end + end + + unless table_exists?("alchemy_languages") + create_table "alchemy_languages" do |t| + t.string "name" + t.string "language_code" + t.string "frontpage_name" + t.string "page_layout", default: "intro" + t.boolean "public", default: false + t.timestamps + t.references "creator" + t.references "updater" + t.boolean "default", default: false + t.string "country_code", default: "", null: false + t.references "site", null: false + t.string "locale" + t.index ["language_code", "country_code"], name: "index_alchemy_languages_on_language_code_and_country_code" + t.index ["language_code"], name: "index_alchemy_languages_on_language_code" + end + end + + unless table_exists?("alchemy_legacy_page_urls") + create_table "alchemy_legacy_page_urls" do |t| + t.string "urlname", null: false + t.references "page", null: false + t.timestamps + t.index ["urlname"], name: "index_alchemy_legacy_page_urls_on_urlname" + end + end + + unless table_exists?("alchemy_nodes") + create_table "alchemy_nodes" do |t| + t.string "name" + t.string "title" + t.string "url" + t.boolean "nofollow", default: false, null: false + t.boolean "external", default: false, null: false + t.boolean "folded", default: false, null: false + t.references "parent" + t.integer "lft", null: false + t.integer "rgt", null: false + t.integer "depth", default: 0, null: false + t.references "page" + t.references "language", null: false + t.references "creator" + t.references "updater" + t.timestamps + t.references "site", null: false + t.index ["lft"], name: "index_alchemy_nodes_on_lft" + t.index ["rgt"], name: "index_alchemy_nodes_on_rgt" + end + end + + unless table_exists?("alchemy_pages") + create_table "alchemy_pages" do |t| + t.string "name" + t.string "urlname" + t.string "title" + t.string "language_code" + t.boolean "language_root" + t.string "page_layout" + t.text "meta_keywords" + t.text "meta_description" + t.integer "lft" + t.integer "rgt" + t.references "parent", index: false + t.integer "depth" + t.boolean "visible", default: false + t.integer "locked_by" + t.boolean "restricted", default: false + t.boolean "robot_index", default: true + t.boolean "robot_follow", default: true + t.boolean "sitemap", default: true + t.boolean "layoutpage", default: false + t.timestamps + t.references "creator" + t.references "updater" + t.references "language" + t.datetime "published_at" + t.datetime "public_on" + t.datetime "public_until" + t.datetime "locked_at" + t.index ["locked_at", "locked_by"], name: "index_alchemy_pages_on_locked_at_and_locked_by" + t.index ["parent_id", "lft"], name: "index_pages_on_parent_id_and_lft" + t.index ["public_on", "public_until"], name: "index_alchemy_pages_on_public_on_and_public_until" + t.index ["rgt"], name: "index_alchemy_pages_on_rgt" + t.index ["urlname"], name: "index_pages_on_urlname" + end + end + + unless table_exists?("alchemy_pictures") + create_table "alchemy_pictures" do |t| + t.string "name" + t.string "image_file_name" + t.integer "image_file_width" + t.integer "image_file_height" + t.timestamps + t.references "creator" + t.references "updater" + t.string "upload_hash" + t.string "image_file_uid" + t.integer "image_file_size" + t.string "image_file_format" + end + end + + unless table_exists?("alchemy_sites") + create_table "alchemy_sites" do |t| + t.string "host" + t.string "name" + t.timestamps + t.boolean "public", default: false + t.text "aliases" + t.boolean "redirect_to_primary_host" + t.index ["host", "public"], name: "alchemy_sites_public_hosts_idx" + t.index ["host"], name: "index_alchemy_sites_on_host" + end + end + + unless foreign_key_exists?("alchemy_elements", column: "page_id") + add_foreign_key "alchemy_elements", "alchemy_pages", column: "page_id", on_update: :cascade, on_delete: :cascade + end + + unless foreign_key_exists?("alchemy_nodes", column: "language_id") + add_foreign_key "alchemy_nodes", "alchemy_languages", column: "language_id" + end + + unless foreign_key_exists?("alchemy_nodes", column: "page_id") + add_foreign_key "alchemy_nodes", "alchemy_pages", column: "page_id", on_delete: :cascade + end + + unless foreign_key_exists?("alchemy_nodes", column: "site_id") + add_foreign_key "alchemy_nodes", "alchemy_sites", column: "site_id", on_delete: :cascade + end + end + + def down + drop_table "alchemy_attachments" if table_exists?("alchemy_attachments") + drop_table "alchemy_elements" if table_exists?("alchemy_elements") + drop_table "alchemy_elements_alchemy_pages" if table_exists?("alchemy_elements_alchemy_pages") + drop_table "alchemy_folded_pages" if table_exists?("alchemy_folded_pages") + drop_table "alchemy_languages" if table_exists?("alchemy_languages") + drop_table "alchemy_legacy_page_urls" if table_exists?("alchemy_legacy_page_urls") + drop_table "alchemy_nodes" if table_exists?("alchemy_nodes") + drop_table "alchemy_pages" if table_exists?("alchemy_pages") + drop_table "alchemy_pictures" if table_exists?("alchemy_pictures") + drop_table "alchemy_sites" if table_exists?("alchemy_sites") + end +end diff --git a/spec/dummy/db/migrate/20230119091718_remove_site_id_from_nodes.alchemy.rb b/spec/dummy/db/migrate/20230119091718_remove_site_id_from_nodes.alchemy.rb new file mode 100644 index 0000000000..59564ec617 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091718_remove_site_id_from_nodes.alchemy.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true +# This migration comes from alchemy (originally 20200504210159) +class RemoveSiteIdFromNodes < ActiveRecord::Migration[6.0] + def up + remove_foreign_key :alchemy_nodes, :alchemy_sites + remove_index :alchemy_nodes, :site_id + remove_column :alchemy_nodes, :site_id, :integer, null: false + end + + def down + add_column :alchemy_nodes, :site_id, :integer, null: true + sql = <<~SQL + UPDATE alchemy_nodes + SET site_id = ( + SELECT alchemy_languages.site_id FROM alchemy_languages WHERE alchemy_nodes.language_id = alchemy_languages.id + ) WHERE + EXISTS ( + SELECT * + FROM alchemy_languages + WHERE alchemy_languages.id = alchemy_nodes.language_id + ); + SQL + + connection.execute(sql) + change_column :alchemy_nodes, :site_id, :integer, null: false + add_index :alchemy_nodes, :site_id + add_foreign_key :alchemy_nodes, :alchemy_sites, column: :site_id + end +end diff --git a/spec/dummy/db/migrate/20230119091719_add_language_id_foreign_key_to_alchemy_pages.alchemy.rb b/spec/dummy/db/migrate/20230119091719_add_language_id_foreign_key_to_alchemy_pages.alchemy.rb new file mode 100644 index 0000000000..01cb10ef48 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091719_add_language_id_foreign_key_to_alchemy_pages.alchemy.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +# This migration comes from alchemy (originally 20200505215518) +class AddLanguageIdForeignKeyToAlchemyPages < ActiveRecord::Migration[6.0] + def change + add_foreign_key :alchemy_pages, :alchemy_languages, column: :language_id + change_column_null :alchemy_pages, :language_id, false, Alchemy::Language.default&.id + end +end diff --git a/spec/dummy/db/migrate/20230119091720_add_menu_type_to_alchemy_nodes.alchemy.rb b/spec/dummy/db/migrate/20230119091720_add_menu_type_to_alchemy_nodes.alchemy.rb new file mode 100644 index 0000000000..9e98022898 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091720_add_menu_type_to_alchemy_nodes.alchemy.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true +# This migration comes from alchemy (originally 20200511113603) +class AddMenuTypeToAlchemyNodes < ActiveRecord::Migration[6.0] + class LocalNode < ActiveRecord::Base + self.table_name = :alchemy_nodes + acts_as_nested_set scope: :language_id + + def self.root_for(node) + return node if node.parent_id.nil? + + root_for(node.parent) + end + end + + def up + add_column :alchemy_nodes, :menu_type, :string + LocalNode.all.each do |node| + root = LocalNode.root_for(node) + menu_type = root.name.parameterize.underscore + node.update(menu_type: menu_type) + end + change_column_null :alchemy_nodes, :menu_type, false + end + + def down + remove_column :alchemy_nodes, :menu_type + end +end diff --git a/spec/dummy/db/migrate/20230119091721_make_page_layoutpage_null_false.alchemy.rb b/spec/dummy/db/migrate/20230119091721_make_page_layoutpage_null_false.alchemy.rb new file mode 100644 index 0000000000..c96ca75062 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091721_make_page_layoutpage_null_false.alchemy.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true +# This migration comes from alchemy (originally 20200514091507) +class MakePageLayoutpageNullFalse < ActiveRecord::Migration[6.0] + def change + change_column_null :alchemy_pages, :layoutpage, false, false + end +end diff --git a/spec/dummy/db/migrate/20230119091722_remove_visible_from_alchemy_pages.alchemy.rb b/spec/dummy/db/migrate/20230119091722_remove_visible_from_alchemy_pages.alchemy.rb new file mode 100644 index 0000000000..31dd81fb51 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091722_remove_visible_from_alchemy_pages.alchemy.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true +# This migration comes from alchemy (originally 20200519073500) +class RemoveVisibleFromAlchemyPages < ActiveRecord::Migration[6.0] + class LocalPage < ActiveRecord::Base + self.table_name = "alchemy_pages" + + scope :invisible, -> { where(visible: [false, nil]) } + scope :contentpages, -> { where(layoutpage: [false, nil]) } + end + + def up + if LocalPage.invisible.contentpages.where.not(parent_id: nil).any? + abort "You have invisible pages in your database! " \ + "Please re-structure your page tree before running this migration. " \ + "You might also downgrade to Alchemy 4.6 and " \ + "run the `alchemy:upgrade:4.6:restructure_page_tree` rake task." + end + + remove_column :alchemy_pages, :visible + end + + def down + add_column :alchemy_pages, :visible, :boolean, default: false + end +end diff --git a/spec/dummy/db/migrate/20230119091723_create_alchemy_picture_thumbs.alchemy.rb b/spec/dummy/db/migrate/20230119091723_create_alchemy_picture_thumbs.alchemy.rb new file mode 100644 index 0000000000..08e2235d73 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091723_create_alchemy_picture_thumbs.alchemy.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# This migration comes from alchemy (originally 20200617110713) +class CreateAlchemyPictureThumbs < ActiveRecord::Migration[6.0] + def up + return if table_exists?(:alchemy_picture_thumbs) + + create_table :alchemy_picture_thumbs do |t| + t.references :picture, foreign_key: { to_table: :alchemy_pictures }, null: false + t.string :signature, null: false + t.text :uid, null: false + end + add_index :alchemy_picture_thumbs, :signature, unique: true + end + + def down + return unless table_exists?(:alchemy_picture_thumbs) + + remove_foreign_key :alchemy_picture_thumbs, :alchemy_pictures, column: :picture_id + remove_index :alchemy_picture_thumbs, :signature + drop_table :alchemy_picture_thumbs + end +end diff --git a/spec/dummy/db/migrate/20230119091724_remove_tri_state_booleans.alchemy.rb b/spec/dummy/db/migrate/20230119091724_remove_tri_state_booleans.alchemy.rb new file mode 100644 index 0000000000..e3e7293190 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091724_remove_tri_state_booleans.alchemy.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# This migration comes from alchemy (originally 20200907111332) +class RemoveTriStateBooleans < ActiveRecord::Migration[6.0] + def change + change_column_null :alchemy_elements, :public, false, false + change_column_default :alchemy_elements, :public, true + + change_column_null :alchemy_elements, :folded, false + change_column_null :alchemy_elements, :unique, false + + change_column_null :alchemy_folded_pages, :folded, false + + change_column_null :alchemy_languages, :public, false + change_column_null :alchemy_languages, :default, false + + change_column_null :alchemy_pages, :language_root, false, false + change_column_default :alchemy_pages, :language_root, false + + change_column_null :alchemy_pages, :restricted, false + change_column_null :alchemy_pages, :robot_index, false + change_column_null :alchemy_pages, :robot_follow, false + change_column_null :alchemy_pages, :sitemap, false + + change_column_null :alchemy_sites, :public, false + change_column_null :alchemy_sites, :redirect_to_primary_host, false, false + change_column_default :alchemy_sites, :redirect_to_primary_host, false + end +end diff --git a/spec/dummy/db/migrate/20230119091725_create_page_versions.alchemy.rb b/spec/dummy/db/migrate/20230119091725_create_page_versions.alchemy.rb new file mode 100644 index 0000000000..aac2252468 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091725_create_page_versions.alchemy.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# This migration comes from alchemy (originally 20201207131309) +class CreatePageVersions < ActiveRecord::Migration[6.0] + def change + create_table :alchemy_page_versions do |t| + t.references :page, + null: false, + index: true, + foreign_key: { + to_table: :alchemy_pages, + on_delete: :cascade, + } + t.datetime :public_on + t.datetime :public_until + t.index [:public_on, :public_until] + t.timestamps + end + end +end diff --git a/spec/dummy/db/migrate/20230119091726_add_page_version_id_to_alchemy_elements.alchemy.rb b/spec/dummy/db/migrate/20230119091726_add_page_version_id_to_alchemy_elements.alchemy.rb new file mode 100644 index 0000000000..fe63be1735 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091726_add_page_version_id_to_alchemy_elements.alchemy.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +# This migration comes from alchemy (originally 20201207135820) +class AddPageVersionIdToAlchemyElements < ActiveRecord::Migration[6.0] + class LocalPage < ActiveRecord::Base + self.table_name = :alchemy_pages + has_many :elements, class_name: "LocalElement", inverse_of: :page + has_many :versions, class_name: "LocalVersion", inverse_of: :page, foreign_key: :page_id + end + + class LocalVersion < ActiveRecord::Base + self.table_name = :alchemy_page_versions + belongs_to :page, class_name: "LocalPage", inverse_of: :versions + has_many :elements, class_name: "LocalElement", inverse_of: :versions + end + + class LocalElement < ActiveRecord::Base + self.table_name = :alchemy_elements + belongs_to :page, class_name: "LocalPage", inverse_of: :elements + belongs_to :page_version, class_name: "LocalVersion", inverse_of: :elements + end + + def change + add_reference :alchemy_elements, :page_version, + index: false, + foreign_key: { + to_table: :alchemy_page_versions, + on_delete: :cascade, + } + add_index :alchemy_elements, [:page_version_id, :parent_element_id], + name: "idx_alchemy_elements_on_page_version_id_and_parent_element_id" + add_index :alchemy_elements, [:page_version_id, :position], + name: "idx_alchemy_elements_on_page_version_id_and_position" + + # Add a page version for each page so we can add a not null constraint + reversible do |dir| + dir.up do + say_with_time "Create draft version for each page." do + LocalPage.find_each do |page| + next if page.versions.any? + + page.versions.create!.tap do |version| + Alchemy::Element.where(page_id: page.id).update_all(page_version_id: version.id) + end + end + LocalVersion.count + end + end + end + + change_column_null :alchemy_elements, :page_version_id, false + + # Remove the existing page relation + remove_reference :alchemy_elements, :page, + null: false, + index: false, + foreign_key: { + to_table: :alchemy_pages, + on_delete: :cascade, + on_update: :cascade, + } + if index_exists? :alchemy_elements, + :parent_element_id, + name: "index_alchemy_elements_on_page_id_and_parent_element_id" + remove_index :alchemy_elements, + column: [:parent_element_id], + name: "index_alchemy_elements_on_page_id_and_parent_element_id" + end + if index_exists? :alchemy_elements, + :position, + name: "index_elements_on_page_id_and_position" + remove_index :alchemy_elements, + column: [:position], + name: "index_elements_on_page_id_and_position" + end + end +end diff --git a/spec/dummy/db/migrate/20230119091727_rename_public_on_and_public_until_on_alchemy_pages.alchemy.rb b/spec/dummy/db/migrate/20230119091727_rename_public_on_and_public_until_on_alchemy_pages.alchemy.rb new file mode 100644 index 0000000000..ff8c1df65e --- /dev/null +++ b/spec/dummy/db/migrate/20230119091727_rename_public_on_and_public_until_on_alchemy_pages.alchemy.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# This migration comes from alchemy (originally 20210205143548) +class RenamePublicOnAndPublicUntilOnAlchemyPages < ActiveRecord::Migration[6.0] + def change + remove_index :alchemy_pages, column: [:public_on, :public_until], + name: "index_alchemy_pages_on_public_on_and_public_until" + rename_column :alchemy_pages, :public_on, :legacy_public_on + rename_column :alchemy_pages, :public_until, :legacy_public_until + end +end diff --git a/spec/dummy/db/migrate/20230119091728_create_alchemy_ingredients.alchemy.rb b/spec/dummy/db/migrate/20230119091728_create_alchemy_ingredients.alchemy.rb new file mode 100644 index 0000000000..19d40e5413 --- /dev/null +++ b/spec/dummy/db/migrate/20230119091728_create_alchemy_ingredients.alchemy.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# This migration comes from alchemy (originally 20210508091432) +class CreateAlchemyIngredients < ActiveRecord::Migration[6.0] + def change + create_table :alchemy_ingredients do |t| + t.references :element, null: false, foreign_key: { to_table: :alchemy_elements, on_delete: :cascade } + t.string :type, index: true, null: false + t.string :role, null: false + t.text :value + if ActiveRecord::Migration.connection.adapter_name.match?(/postgres/i) + t.jsonb :data, default: {} + else + t.json :data + end + t.belongs_to :related_object, null: true, polymorphic: true, index: false + t.index [:element_id, :role], unique: true + t.index [:related_object_id, :related_object_type], name: "idx_alchemy_ingredient_relation" + + t.timestamps + end + end +end diff --git a/spec/dummy/db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb b/spec/dummy/db/migrate/20230119091729_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.alchemy.rb similarity index 81% rename from spec/dummy/db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb rename to spec/dummy/db/migrate/20230119091729_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.alchemy.rb index 0a6a9322a5..ab4a5f553f 100644 --- a/spec/dummy/db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb +++ b/spec/dummy/db/migrate/20230119091729_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.alchemy.rb @@ -1,3 +1,6 @@ +# frozen_string_literal: true + +# This migration comes from alchemy (originally 20220514072456) class RestrictOnDeletePageIdForeignKeyFromAlchemyNodes < ActiveRecord::Migration[6.0] def up remove_foreign_key :alchemy_nodes, :alchemy_pages diff --git a/spec/dummy/db/schema.rb b/spec/dummy/db/schema.rb index 56899f3374..d62183e5fc 100644 --- a/spec/dummy/db/schema.rb +++ b/spec/dummy/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2022_08_31_084620) do +ActiveRecord::Schema[7.0].define(version: 2023_01_19_091729) do create_table "alchemy_attachments", force: :cascade do |t| t.string "name" t.string "file_name" @@ -26,15 +26,6 @@ t.index ["updater_id"], name: "index_alchemy_attachments_on_updater_id" end - create_table "alchemy_contents", force: :cascade do |t| - t.string "name" - t.string "essence_type", null: false - t.integer "essence_id", null: false - t.integer "element_id", null: false - t.index ["element_id"], name: "index_alchemy_contents_on_element_id" - t.index ["essence_type", "essence_id"], name: "index_alchemy_contents_on_essence_type_and_essence_id", unique: true - end - create_table "alchemy_elements", force: :cascade do |t| t.string "name" t.integer "position" @@ -62,114 +53,6 @@ t.index ["page_id"], name: "index_alchemy_elements_alchemy_pages_on_page_id" end - create_table "alchemy_essence_audios", force: :cascade do |t| - t.integer "attachment_id" - t.boolean "controls", default: true, null: false - t.boolean "autoplay", default: false - t.boolean "loop", default: false, null: false - t.boolean "muted", default: false, null: false - t.index ["attachment_id"], name: "index_alchemy_essence_audios_on_attachment_id" - end - - create_table "alchemy_essence_booleans", force: :cascade do |t| - t.boolean "value" - t.index ["value"], name: "index_alchemy_essence_booleans_on_value" - end - - create_table "alchemy_essence_dates", force: :cascade do |t| - t.datetime "date", precision: nil - end - - create_table "alchemy_essence_files", force: :cascade do |t| - t.integer "attachment_id" - t.string "title" - t.string "css_class" - t.string "link_text" - t.index ["attachment_id"], name: "index_alchemy_essence_files_on_attachment_id" - end - - create_table "alchemy_essence_headlines", force: :cascade do |t| - t.text "body" - t.integer "level" - t.integer "size" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "alchemy_essence_htmls", force: :cascade do |t| - t.text "source" - end - - create_table "alchemy_essence_links", force: :cascade do |t| - t.string "link" - t.string "link_title" - t.string "link_target" - t.string "link_class_name" - end - - create_table "alchemy_essence_nodes", force: :cascade do |t| - t.integer "node_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["node_id"], name: "index_alchemy_essence_nodes_on_node_id" - end - - create_table "alchemy_essence_pages", force: :cascade do |t| - t.integer "page_id" - t.index ["page_id"], name: "index_alchemy_essence_pages_on_page_id" - end - - create_table "alchemy_essence_pictures", force: :cascade do |t| - t.integer "picture_id" - t.string "caption" - t.string "title" - t.string "alt_tag" - t.string "link" - t.string "link_class_name" - t.string "link_title" - t.string "css_class" - t.string "link_target" - t.string "crop_from" - t.string "crop_size" - t.string "render_size" - t.index ["picture_id"], name: "index_alchemy_essence_pictures_on_picture_id" - end - - create_table "alchemy_essence_richtexts", force: :cascade do |t| - t.text "body" - t.text "stripped_body" - t.boolean "public", default: false, null: false - t.text "sanitized_body" - end - - create_table "alchemy_essence_selects", force: :cascade do |t| - t.string "value" - t.index ["value"], name: "index_alchemy_essence_selects_on_value" - end - - create_table "alchemy_essence_texts", force: :cascade do |t| - t.text "body" - t.string "link" - t.string "link_title" - t.string "link_class_name" - t.boolean "public", default: false, null: false - t.string "link_target" - end - - create_table "alchemy_essence_videos", force: :cascade do |t| - t.integer "attachment_id" - t.string "width" - t.string "height" - t.boolean "allow_fullscreen", default: true, null: false - t.boolean "autoplay", default: false, null: false - t.boolean "controls", default: true, null: false - t.boolean "loop", default: false, null: false - t.boolean "muted", default: false, null: false - t.string "preload" - t.boolean "playsinline", default: false, null: false - t.index ["attachment_id"], name: "index_alchemy_essence_videos_on_attachment_id" - end - create_table "alchemy_folded_pages", force: :cascade do |t| t.integer "page_id", null: false t.integer "user_id", null: false @@ -341,10 +224,6 @@ t.datetime "updated_at", precision: nil, null: false end - create_table "dummy_models", force: :cascade do |t| - t.string "data" - end - create_table "dummy_users", force: :cascade do |t| t.string "email" t.string "password" @@ -397,10 +276,7 @@ t.string "name" end - add_foreign_key "alchemy_contents", "alchemy_elements", column: "element_id", on_update: :cascade, on_delete: :cascade add_foreign_key "alchemy_elements", "alchemy_page_versions", column: "page_version_id", on_delete: :cascade - add_foreign_key "alchemy_essence_nodes", "alchemy_nodes", column: "node_id" - add_foreign_key "alchemy_essence_pages", "alchemy_pages", column: "page_id" add_foreign_key "alchemy_ingredients", "alchemy_elements", column: "element_id", on_delete: :cascade add_foreign_key "alchemy_nodes", "alchemy_languages", column: "language_id" add_foreign_key "alchemy_nodes", "alchemy_pages", column: "page_id", on_delete: :restrict diff --git a/spec/features/admin/edit_elements_feature_spec.rb b/spec/features/admin/edit_elements_feature_spec.rb index 165a7b3d75..125703c5fa 100644 --- a/spec/features/admin/edit_elements_feature_spec.rb +++ b/spec/features/admin/edit_elements_feature_spec.rb @@ -134,49 +134,47 @@ end end - {content: "name", ingredient: "role"}.each do |type, name_field| - describe "With an element that has #{type} groups" do - let(:element) { create(:alchemy_element, page: a_page, name: "element_with_#{type}_groups") } - - # Need to be on page editor rather than just admin_elements in order to have JS interaction - before { visit alchemy.edit_admin_page_path(element.page) } - - scenario "collapsed #{type} groups shown", :js do - # No group content initially visible - expect(page).not_to have_selector(".content-group-contents", visible: true) - - page.find("a#element_#{element.id}_content_group_details_header", text: "Details").click - # 'Details' group content visible - expect(page).to have_selector("#element_#{element.id}_content_group_details", visible: true) - within("#element_#{element.id}_content_group_details") do - expect(page).to have_selector("[data-#{type}-#{name_field}='description']") - expect(page).to have_selector("[data-#{type}-#{name_field}='key_words']") - end - expect(page).to have_selector("#element_#{element.id}_content_group_details", visible: true) - - # 'Size' group content not visible - expect(page).not_to have_selector("#element_#{element.id}_content_group_size", visible: true) + describe "With an element that has ingredient groups" do + let(:element) { create(:alchemy_element, page: a_page, name: "element_with_ingredient_groups") } + + # Need to be on page editor rather than just admin_elements in order to have JS interaction + before { visit alchemy.edit_admin_page_path(element.page) } + + scenario "collapsed ingredient groups shown", :js do + # No group ingredient initially visible + expect(page).not_to have_selector(".ingredient-group-ingredients", visible: true) + + page.find("a#element_#{element.id}_ingredient_group_details_header", text: "Details").click + # 'Details' group ingredient visible + expect(page).to have_selector("#element_#{element.id}_ingredient_group_details", visible: true) + within("#element_#{element.id}_ingredient_group_details") do + expect(page).to have_selector("[data-ingredient-role='description']") + expect(page).to have_selector("[data-ingredient-role='key_words']") + end + expect(page).to have_selector("#element_#{element.id}_ingredient_group_details", visible: true) - page.find("a#element_#{element.id}_content_group_size_header", text: "Size").click - # 'Size' group now visible - expect(page).to have_selector("#element_#{element.id}_content_group_size", visible: true) - within("#element_#{element.id}_content_group_size") do - expect(page).to have_selector("[data-#{type}-#{name_field}='width']") - expect(page).to have_selector("[data-#{type}-#{name_field}='height']") - end + # 'Size' group ingredient not visible + expect(page).not_to have_selector("#element_#{element.id}_ingredient_group_size", visible: true) - page.find("a#element_#{element.id}_content_group_size_header", text: "Size").click - # 'Size' group hidden - expect(page).not_to have_selector("#element_#{element.id}_content_group_size", visible: true) + page.find("a#element_#{element.id}_ingredient_group_size_header", text: "Size").click + # 'Size' group now visible + expect(page).to have_selector("#element_#{element.id}_ingredient_group_size", visible: true) + within("#element_#{element.id}_ingredient_group_size") do + expect(page).to have_selector("[data-ingredient-role='width']") + expect(page).to have_selector("[data-ingredient-role='height']") end - scenario "expanded content groups persist between visits", :js do - expect(page).not_to have_selector("#element_#{element.id}_content_group_details", visible: true) - page.find("a#element_#{element.id}_content_group_details_header", text: "Details").click - expect(page).to have_selector("#element_#{element.id}_content_group_details", visible: true) - visit alchemy.edit_admin_page_path(element.page) - expect(page).to have_selector("#element_#{element.id}_content_group_details", visible: true) - end + page.find("a#element_#{element.id}_ingredient_group_size_header", text: "Size").click + # 'Size' group hidden + expect(page).not_to have_selector("#element_#{element.id}_ingredient_group_size", visible: true) + end + + scenario "expanded ingredient groups persist between visits", :js do + expect(page).not_to have_selector("#element_#{element.id}_ingredient_group_details", visible: true) + page.find("a#element_#{element.id}_ingredient_group_details_header", text: "Details").click + expect(page).to have_selector("#element_#{element.id}_ingredient_group_details", visible: true) + visit alchemy.edit_admin_page_path(element.page) + expect(page).to have_selector("#element_#{element.id}_ingredient_group_details", visible: true) end end end diff --git a/spec/features/admin/link_overlay_spec.rb b/spec/features/admin/link_overlay_spec.rb index 3cab3bbe16..ab0b801a0b 100644 --- a/spec/features/admin/link_overlay_spec.rb +++ b/spec/features/admin/link_overlay_spec.rb @@ -45,10 +45,12 @@ end let!(:article) do - create(:alchemy_element, + create( + :alchemy_element, name: "article", page_version: page1.draft_version, - autogenerate_contents: true) + autogenerate_ingredients: true, + ) end it "should be possible to link a page" do diff --git a/spec/features/admin/node_select_feature_spec.rb b/spec/features/admin/node_select_feature_spec.rb index fa9b276bd0..45389a7040 100644 --- a/spec/features/admin/node_select_feature_spec.rb +++ b/spec/features/admin/node_select_feature_spec.rb @@ -21,13 +21,13 @@ it "restricts to the site/language of the page the element is on" do visit alchemy.admin_elements_path(page_version_id: element.page_version_id) - select2_search("test", element_id: element.id, content_name: "menu") + select2_search("test", element_id: element.id, ingredient_role: "menu") within "#element_#{element.id}" do click_on("Save") end expect(page).to have_content("Saved", wait: 5) - expect(element.reload.ingredient(:menu)).to eq(node) + expect(element.reload.value_for(:menu)).to eq(node) end end end diff --git a/spec/features/admin/page_editing_feature_spec.rb b/spec/features/admin/page_editing_feature_spec.rb index d4d18cab6e..9d4a09837e 100644 --- a/spec/features/admin/page_editing_feature_spec.rb +++ b/spec/features/admin/page_editing_feature_spec.rb @@ -155,32 +155,32 @@ class FooPreviewSource < Alchemy::Admin::PreviewUrl; end create(:alchemy_page, page_layout: "everything", autogenerate_elements: true) end - it "renders essence editors for all element contents" do + it "renders editors for all element ingredients" do visit alchemy.admin_elements_path(page_version_id: everything_page.draft_version.id) - expect(page).to have_selector("div.content_editor.essence_boolean") - expect(page).to have_selector("div.content_editor.essence_date") - expect(page).to have_selector("div.content_editor.essence_file") - expect(page).to have_selector("div.content_editor.essence_html") - expect(page).to have_selector("div.content_editor.essence_link") - expect(page).to have_selector("div.content_editor.essence_picture") - expect(page).to have_selector("div.content_editor.essence_richtext") - expect(page).to have_selector("div.content_editor.essence_select") - expect(page).to have_selector("div.content_editor.essence_text") + expect(page).to have_selector("div.ingredient-editor.boolean") + expect(page).to have_selector("div.ingredient-editor.datetime") + expect(page).to have_selector("div.ingredient-editor.file") + expect(page).to have_selector("div.ingredient-editor.html") + expect(page).to have_selector("div.ingredient-editor.link") + expect(page).to have_selector("div.ingredient-editor.picture") + expect(page).to have_selector("div.ingredient-editor.richtext") + expect(page).to have_selector("div.ingredient-editor.select") + expect(page).to have_selector("div.ingredient-editor.text") end - it "renders data attribute based on content name" do + it "renders data attribute based on ingredient role" do visit alchemy.admin_elements_path(page_version_id: everything_page.draft_version.id) - expect(page).to have_selector("div[data-content-name=essence_boolean]") - expect(page).to have_selector("div[data-content-name=essence_date]") - expect(page).to have_selector("div[data-content-name=essence_file]") - expect(page).to have_selector("div[data-content-name=essence_html]") - expect(page).to have_selector("div[data-content-name=essence_link]") - expect(page).to have_selector("div[data-content-name=essence_picture]") - expect(page).to have_selector("div[data-content-name=essence_richtext]") - expect(page).to have_selector("div[data-content-name=essence_select]") - expect(page).to have_selector("div[data-content-name=essence_text]") + expect(page).to have_selector("div[data-ingredient-role=boolean]") + expect(page).to have_selector("div[data-ingredient-role=date]") + expect(page).to have_selector("div[data-ingredient-role=file]") + expect(page).to have_selector("div[data-ingredient-role=html]") + expect(page).to have_selector("div[data-ingredient-role=link]") + expect(page).to have_selector("div[data-ingredient-role=picture]") + expect(page).to have_selector("div[data-ingredient-role=richtext]") + expect(page).to have_selector("div[data-ingredient-role=select]") + expect(page).to have_selector("div[data-ingredient-role=text]") end end end diff --git a/spec/features/admin/picture_assignment_overlay_spec.rb b/spec/features/admin/picture_assignment_overlay_spec.rb index a62a91a5f9..e178d282be 100644 --- a/spec/features/admin/picture_assignment_overlay_spec.rb +++ b/spec/features/admin/picture_assignment_overlay_spec.rb @@ -9,11 +9,11 @@ describe "assigning an image" do let!(:picture) { create(:alchemy_picture) } - let(:element) { create(:alchemy_element, :with_contents, name: "header") } - let(:content) { element.contents.last } + let(:element) { create(:alchemy_element, :with_ingredients, name: "header") } + let(:ingredient) { element.ingredients.last } - scenario "it has link to assign picture to content" do - visit alchemy.admin_pictures_path(form_field_id: "contents_#{content.id}_picture_id") + scenario "it has link to assign picture to ingredient" do + visit alchemy.admin_pictures_path(form_field_id: "ingredients_#{ingredient.id}_picture_id") expect(page).to have_css %(a[data-method="put"][href*="/admin/pictures/#{picture.id}/assign"]) end end diff --git a/spec/features/admin/resources_integration_spec.rb b/spec/features/admin/resources_integration_spec.rb index cf13fc6c22..ba67914615 100644 --- a/spec/features/admin/resources_integration_spec.rb +++ b/spec/features/admin/resources_integration_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe "Resources", type: :system do - let(:event) { create(:event) } + let(:event) { create(:event) } let(:second_event) { create(:event, name: "My second Event", entrance_fee: 12.32) } before { authorize_user(:as_admin) } @@ -294,7 +294,7 @@ end context "with tagged events in the index view" do - let!(:event) { create(:event, name: "Casablanca", tag_list: "Matinee") } + let!(:event) { create(:event, name: "Casablanca", tag_list: "Matinee") } let!(:second_event) { create(:event, name: "Die Hard IX", tag_list: "Late Show") } before { visit "/admin/events" } @@ -334,19 +334,19 @@ # Here we visit the pages manually, as we don't want to test the JS here. visit "/admin/events?filter[start]=starting_today" - expect(page).to have_content("Car Expo") + expect(page).to have_content("Car Expo") expect(page).to_not have_content("Hovercar Expo") expect(page).to_not have_content("Horse Expo") visit "/admin/events?filter[start]=future" - expect(page).to have_content("Hovercar Expo") + expect(page).to have_content("Hovercar Expo") expect(page).to_not have_content("Car Expo") expect(page).to_not have_content("Horse Expo") # Keep the filter when editing an event click_link "Edit" click_button "Save" - expect(page).to have_content("Hovercar Expo") + expect(page).to have_content("Hovercar Expo") expect(page).to_not have_content("Car Expo") expect(page).to_not have_content("Horse Expo") end diff --git a/spec/features/page_feature_spec.rb b/spec/features/page_feature_spec.rb index 622faa8e19..f6d0608336 100644 --- a/spec/features/page_feature_spec.rb +++ b/spec/features/page_feature_spec.rb @@ -37,10 +37,10 @@ context "rendered" do let(:public_page) { create(:alchemy_page, :public, autogenerate_elements: true) } let(:article) { public_page.elements.find_by_name("article") } - let(:essence) { article.content_by_name("intro").essence } + let(:ingredient) { article.ingredient_by_role("intro") } before do - essence.update_columns(body: "Welcome to Peters Petshop", public: true) + ingredient.update_columns(value: "Welcome to Peters Petshop") end it "should include all its elements and contents" do diff --git a/spec/helpers/alchemy/admin/base_helper_spec.rb b/spec/helpers/alchemy/admin/base_helper_spec.rb index abab59dd87..fe87917916 100644 --- a/spec/helpers/alchemy/admin/base_helper_spec.rb +++ b/spec/helpers/alchemy/admin/base_helper_spec.rb @@ -10,7 +10,7 @@ module Alchemy it "renders a toolbar button" do expect(helper.toolbar_button( - url: admin_dashboard_path, + url: admin_dashboard_path, )).to match / "foo", - "contents" => [{ "name" => "title" }], - }, - { - "name" => "bar", - }, - ] - end - end - - it "returns only content definitions" do - expect(Content.definitions).to match_array( - [{ "name" => "title" }], - ) - end - end - end - - describe ".new" do - let(:element) { build(:alchemy_element) } - - subject { Content.new({ element: element, name: "headline" }) } - - it "builds a new content instance from elements.yml definition" do - is_expected.to be_instance_of(Content) - is_expected.to_not be_persisted - end - - it "builds a new essence instance from elements.yml definition" do - expect(subject.essence).to be_instance_of(EssenceText) - expect(subject.essence).to_not be_persisted - end - - context "when given an essence_type attribute that is not in the definition" do - let(:arguments) { { element: element, essence_type: "Alchemy::EssenceText", name: "not_in_elements_yml" } } - - subject { Content.new(arguments) } - - it "does not raise an error" do - expect { subject }.not_to raise_exception - expect(subject.name).to eq("not_in_elements_yml") - expect(subject.essence).to be_a(Alchemy::EssenceText) - end - end - end - - describe ".create" do - let(:element) { create(:alchemy_element, name: "article") } - - subject(:content) { Content.create(element: element, name: "headline") } - - it "creates the content" do - is_expected.to be_instance_of(Alchemy::Content) - is_expected.to be_persisted - end - - it "creates the essence" do - expect(subject.essence).to be_instance_of(Alchemy::EssenceText) - expect(subject.essence).to be_persisted - end - - context "with default value present" do - it "should have the ingredient column filled with default value." do - allow_any_instance_of(Content).to receive(:definition) do - { - "name" => "headline", - "type" => "EssenceText", - "default" => "Welcome", - }.with_indifferent_access - end - expect(content.ingredient).to eq("Welcome") - end - - context "with default value being a symbol" do - it "passes default value through I18n." do - allow_any_instance_of(Content).to receive(:definition) do - { - "name" => "headline", - "type" => "EssenceText", - "default" => :welcome, - }.with_indifferent_access - end - expect(content.ingredient).to eq("Welcome to my site") - end - end - end - end - - describe "#ingredient=" do - let(:element) { create(:alchemy_element, name: "headline") } - - it "should set the given value to the ingredient column of essence" do - c = Content.create(element: element, name: "headline") - c.ingredient = "Welcome" - expect(c.ingredient).to eq("Welcome") - end - - context "no essence associated" do - let(:element) { create(:alchemy_element, name: "headline") } - let(:content) { Alchemy::Content.new(element: element, name: "headline").tap(&:save) } - - before do - expect(content).to receive(:essence) { nil } - end - - it "should raise error" do - expect { content.ingredient = "Welcome" }.to raise_error(EssenceMissingError) - end - end - end - - describe "#dom_id" do - let(:content) { build_stubbed(:alchemy_content) } - - it "returns a dom id string" do - expect(content.dom_id).to eq("essence_text_#{content.id}") - end - - context "without an essence" do - before { expect(content).to receive(:essence).and_return nil } - - it "returns empty string" do - expect(content.dom_id).to eq("") - end - end - end - - describe "#essence_partial_name" do - let(:content) { build_stubbed(:alchemy_content) } - - it "returns the essence#partial_name" do - expect(content.essence).to receive(:partial_name) - content.essence_partial_name - end - - context "without an essence" do - before { expect(content).to receive(:essence).and_return nil } - - it "returns empty string" do - expect(content.essence_partial_name).to eq("") - end - end - end - - describe "#deprecated?" do - let(:content) { build_stubbed(:alchemy_content) } - - subject { content.deprecated? } - - context "not defined as deprecated" do - it "returns false" do - expect(content.deprecated?).to be false - end - end - - context "defined as deprecated" do - before do - expect(content).to receive(:definition).at_least(:once).and_return({ - "deprecated" => true, - }) - end - - it "returns true" do - expect(content.deprecated?).to be true - end - end - - context "defined as deprecated per String" do - before do - expect(content).to receive(:definition).at_least(:once).and_return({ - "deprecated" => "This content is deprecated", - }) - end - - it "returns true" do - expect(content.deprecated?).to be true - end - end - end - - describe "#preview_content?" do - let(:content) { build_stubbed(:alchemy_content) } - - context "not defined as preview content" do - it "returns false" do - expect(content.preview_content?).to be false - end - end - - context "defined as preview content" do - before do - expect(content).to receive(:definition).at_least(:once).and_return({ - "as_element_title" => true, - }) - end - - it "returns true" do - expect(content.preview_content?).to be true - end - end - end - - describe "#preview_text" do - let(:essence) { mock_model(EssenceText, preview_text: "Lorem") } - let(:content) { c = Content.new; c.essence = essence; c } - - it "should return the essences preview_text" do - expect(essence).to receive(:preview_text).with(30) - content.preview_text - end - end - - describe "#has_tinymce?" do - let(:element) { build_stubbed(:alchemy_element, name: "article") } - let(:content) { build_stubbed(:alchemy_content, name: "text", element: element) } - - subject { content.has_tinymce? } - - it { is_expected.to eq(false) } - - context "having custom tinymce config hash" do - before do - expect(content).to receive(:settings) do - { tinymce: { toolbar: [] } } - end - end - - it { is_expected.to eq(true) } - end - - context "having essence that has_tinymce? eq true" do - before do - expect(content.essence).to receive(:has_tinymce?) { true } - end - - it { is_expected.to eq(true) } - end - - context "having nil essence" do - before do - content.essence = nil - end - - it { is_expected.to eq(false) } - end - end - - describe "#has_custom_tinymce_config?" do - let(:element) { build_stubbed(:alchemy_element, name: "article") } - let(:content) { build_stubbed(:alchemy_content, name: "text", element: element) } - - subject { content.has_custom_tinymce_config? } - - it { is_expected.to eq(false) } - - context "having custom tinymce config hash" do - before do - expect(content).to receive(:settings) do - { tinymce: { toolbar: [] } } - end - end - - it { is_expected.to eq(true) } - end - end - - describe "#tinymce_class_name" do - let(:element) { build_stubbed(:alchemy_element, name: "article") } - let(:content) { build_stubbed(:alchemy_content, name: "text", element: element) } - - subject { content.tinymce_class_name } - - it { is_expected.to eq("has_tinymce") } - - context "having custom tinymce config" do - before do - expect(content).to receive(:has_custom_tinymce_config?).and_return(true) - end - - it "returns name including element name" do - is_expected.to eq("has_tinymce article_text") - end - end - end - - it_behaves_like "having a hint" do - let(:subject) { Content.new } - end - - describe "#settings" do - let(:element) { build_stubbed(:alchemy_element, name: "article") } - let(:content) { build_stubbed(:alchemy_content, name: "headline", element: element) } - - it "returns the settings hash from definition" do - expect(content.settings).to eq({ "linkable" => true }) - end - - context "if settings are not defined" do - let(:content) { build_stubbed(:alchemy_content, name: "intro", element: element) } - - it "returns empty hash" do - expect(content.settings).to eq({}) - end - end - end - - describe "#settings_value" do - let(:key) { :key } - let(:settings) { Hash.new } - - subject { content.settings_value(key, options) } - - before do - allow(content).to receive(:settings) { settings } - end - - context "with content having settings" do - let(:settings) { { key: "settings_value" } } - - context "and empty options" do - let(:options) { {} } - - it "returns the value for key from content settings" do - expect(subject).to eq("settings_value") - end - end - - context "and nil options" do - let(:options) { nil } - - it "returns the value for key from content settings" do - expect(subject).to eq("settings_value") - end - end - - context "but same key present in options" do - let(:options) { { key: "options_value" } } - - it "returns the value for key from options" do - expect(subject).to eq("options_value") - end - end - end - - context "with content having no settings" do - let(:settings) { {} } - - context "and empty options" do - let(:options) { {} } - - it { expect(subject).to eq(nil) } - end - - context "but key present in options" do - let(:options) { { key: "options_value" } } - - it "returns the value for key from options" do - expect(subject).to eq("options_value") - end - end - end - - context "with content having settings with string as key" do - let(:settings) { { "key" => "value_from_string_key" } } - let(:options) { {} } - - it "returns value" do - expect(subject).to eq("value_from_string_key") - end - end - - context "with key passed as string" do - let(:settings) { { key: "value_from_symbol_key" } } - let(:key) { "key" } - let(:options) { {} } - - it "returns value" do - expect(subject).to eq("value_from_symbol_key") - end - end - end - - context "delegations" do - let(:page) { create(:alchemy_page, :restricted) } - - it "delegates restricted? to page" do - element.update!(page: page) - expect(page.restricted?).to be true - expect(content.page).to eq page - expect(content.restricted?).to be true - end - - it "delegates public? to element" do - element.update!(public: false) - expect(element.public?).to be false - expect(content.public?).to be false - end - end - end -end diff --git a/spec/models/alchemy/eager_loading_spec.rb b/spec/models/alchemy/eager_loading_spec.rb index e8c52fed3b..c73c951a7e 100644 --- a/spec/models/alchemy/eager_loading_spec.rb +++ b/spec/models/alchemy/eager_loading_spec.rb @@ -19,7 +19,6 @@ :tags, { ingredients: :related_object, - contents: :essence, }, ], }, @@ -43,7 +42,6 @@ :tags, { ingredients: :related_object, - contents: :essence, }, ], }, diff --git a/spec/models/alchemy/element_ingredients_spec.rb b/spec/models/alchemy/element_ingredients_spec.rb index b4cb940092..f52c7fdd4f 100644 --- a/spec/models/alchemy/element_ingredients_spec.rb +++ b/spec/models/alchemy/element_ingredients_spec.rb @@ -10,7 +10,7 @@ it "creates ingredients after creation" do expect { element.save! - }.to change { element.ingredients.count }.by(2) + }.to change { element.ingredients.count }.by(4) end describe "#ingredients_by_type" do @@ -164,4 +164,50 @@ ]) end end + + describe "#richtext_ingredients_ids" do + subject { element.richtext_ingredients_ids } + + let(:element) { create(:alchemy_element, :with_ingredients, name: "text") } + + it { is_expected.to eq(element.ingredient_ids) } + + context "for element with nested elements" do + let!(:element) do + create(:alchemy_element, :with_ingredients, name: "text") + end + + let!(:nested_element_1) do + create(:alchemy_element, :with_ingredients, { + name: "text", + parent_element: element, + folded: false, + }) + end + + let!(:nested_element_2) do + create(:alchemy_element, :with_ingredients, { + name: "text", + parent_element: nested_element_1, + folded: false, + }) + end + + let!(:folded_nested_element_3) do + create(:alchemy_element, :with_ingredients, { + name: "text", + parent_element: nested_element_1, + folded: true, + }) + end + + it "includes all richtext ingredients from all expanded descendent elements" do + is_expected.to eq( + element.ingredient_ids + + nested_element_1.ingredient_ids + + nested_element_2.ingredient_ids, + ) + end + end + end end diff --git a/spec/models/alchemy/element_spec.rb b/spec/models/alchemy/element_spec.rb index cd5398e677..eefaee0e13 100644 --- a/spec/models/alchemy/element_spec.rb +++ b/spec/models/alchemy/element_spec.rb @@ -31,7 +31,7 @@ module Alchemy it "should not have forbidden attributes from definition" do el = Element.new(name: "article") - expect(el.contents).to eq([]) + expect(el.ingredients).to eq([]) end end @@ -39,55 +39,20 @@ module Alchemy let(:page_version) { build(:alchemy_page_version) } subject(:element) do - described_class.create(page_version: page_version, name: "article", autogenerate_contents: true) + described_class.create(page_version: page_version, name: "article", autogenerate_ingredients: true) end - it "creates contents" do - expect(element.contents).to match_array([ - an_instance_of(Alchemy::Content), - an_instance_of(Alchemy::Content), - an_instance_of(Alchemy::Content), - an_instance_of(Alchemy::Content), - ]) - end - - context "if autogenerate_contents set to false" do + context "if autogenerate_ingredients set to false" do subject(:element) do described_class.create( page_version: page_version, name: "article", - autogenerate_contents: false, + autogenerate_ingredients: false, ) end - it "does not create contents" do - expect(element.contents).to be_empty - end - end - - context "if ingredients are defined as well" do - before do - expect_any_instance_of(Alchemy::Element).to receive(:definition).at_least(:once) do - { - name: "article", - contents: [ - { - name: "headline", - type: "EssenceText", - }, - ], - ingredients: [ - { - role: "headline", - type: "Text", - }, - ], - }.with_indifferent_access - end - end - - it "does not create contents" do - expect(element.contents).to be_empty + it "does not create ingredients" do + expect(element.ingredients).to be_empty end end @@ -144,8 +109,8 @@ module Alchemy ) end - it "creates contents" do - expect(element.contents).to be_empty + it "does not create ingredients" do + expect(element.ingredients).to be_empty end end end @@ -176,11 +141,11 @@ module Alchemy subject { Element.copy(element) } let(:element) do - create(:alchemy_element, :with_contents, tag_list: "red, yellow") + create(:alchemy_element, :with_ingredients, tag_list: "red, yellow") end it "should not create contents from scratch" do - expect(subject.contents.count).to eq(element.contents.count) + expect(subject.ingredients.count).to eq(element.ingredients.count) end context "with differences" do @@ -192,9 +157,9 @@ module Alchemy end end - it "should make copies of all contents of source" do - expect(subject.contents).not_to be_empty - expect(subject.contents.pluck(:id)).not_to eq(element.contents.pluck(:id)) + it "should make copies of all ingredients of source" do + expect(subject.ingredients).not_to be_empty + expect(subject.ingredients.pluck(:id)).not_to eq(element.ingredients.pluck(:id)) end it "the copy should include source element tags" do @@ -203,7 +168,7 @@ module Alchemy context "with nested elements" do let(:element) do - create(:alchemy_element, :with_contents, :with_nestable_elements, { + create(:alchemy_element, :with_ingredients, :with_nestable_elements, { tag_list: "red, yellow", page: create(:alchemy_page), }) @@ -477,42 +442,6 @@ module Alchemy # InstanceMethods - describe "#all_contents_by_type" do - let(:element) { create(:alchemy_element, :with_contents) } - let(:expected_contents) { element.contents.essence_texts } - - context "with namespaced essence type" do - subject { element.all_contents_by_type("Alchemy::EssenceText") } - it { is_expected.not_to be_empty } - it("should return the correct list of essences") { is_expected.to eq(expected_contents) } - end - - context "without namespaced essence type" do - subject { element.all_contents_by_type("EssenceText") } - it { is_expected.not_to be_empty } - it("should return the correct list of essences") { is_expected.to eq(expected_contents) } - end - end - - describe "#content_by_type" do - before(:each) do - @element = create(:alchemy_element, name: "headline") - @content = @element.contents.first - end - - context "with namespaced essence type" do - it "should return content by passing a essence type" do - expect(@element.content_by_type("Alchemy::EssenceText")).to eq(@content) - end - end - - context "without namespaced essence type" do - it "should return content by passing a essence type" do - expect(@element.content_by_type("EssenceText")).to eq(@content) - end - end - end - describe "#display_name" do let(:element) { Element.new(name: "article") } @@ -522,46 +451,6 @@ module Alchemy end end - describe "#essence_errors" do - let(:element) { Element.new(name: "article") } - let(:content) { Content.new(name: "headline") } - let(:essence) { EssenceText.new(body: "") } - - before do - allow(element).to receive(:contents) { [content] } - allow(content).to receive(:essence) { essence } - allow(content).to receive(:essence_validation_failed?) { true } - allow(essence).to receive(:validation_errors) { "Cannot be blank" } - end - - it "returns hash with essence errors" do - expect(element.essence_errors).to eq({ "headline" => "Cannot be blank" }) - end - end - - describe "#essence_error_messages" do - let(:element) { Element.new(name: "article") } - - it "should return the translation with the translated content label" do - expect(Alchemy).to receive(:t) - .with("content_names.content", default: "Content") - .and_return("Content") - expect(Alchemy).to receive(:t) - .with("content", scope: "content_names.article", default: "Content") - .and_return("Contenido") - expect(Alchemy).to receive(:t) - .with("article.content.invalid", { - scope: "content_validations", - default: [:"fields.content.invalid", :"errors.invalid"], - field: "Contenido", - }) - expect(element).to receive(:essence_errors) - .and_return({ "content" => [:invalid] }) - - element.essence_error_messages - end - end - describe "#display_name_with_preview_text" do let(:element) { build_stubbed(:alchemy_element, name: "Foo") } @@ -591,7 +480,7 @@ module Alchemy end let(:ingredient_2) do - mock_model(Ingredients::Text, role: "headline", preview_text: "Ingredient 2", preview_ingredient?: false) + mock_model(Ingredients::Text, role: "intro", preview_text: "Ingredient 2", preview_ingredient?: false) end let(:ingredients) { [] } @@ -629,65 +518,8 @@ module Alchemy end end - context "with element having contents" do - let(:content) do - mock_model(Content, preview_text: "Content 1", preview_content?: false) - end - - let(:content_2) do - mock_model(Content, preview_text: "Content 2", preview_content?: false) - end - - let(:contents) { [] } - - let(:preview_content) do - mock_model(Content, preview_text: "Preview Content", preview_content?: true) - end - - before do - allow(element).to receive(:contents).and_return(contents) - end - - context "without a content marked as preview" do - let(:contents) { [content, content_2] } - - it "returns the preview text of first content found" do - expect(content).to receive(:preview_text).with(60) - element.preview_text - end - end - - context "with a content marked as preview" do - let(:contents) { [content, preview_content] } - - it "should return the preview_text of this content" do - expect(preview_content).to receive(:preview_text).with(60) - element.preview_text - end - end - - context "without any contents present" do - it "should return nil" do - expect(element.preview_text).to be_nil - end - end - end - context "with nested elements" do - let(:element) do - build_stubbed(:alchemy_element, :with_nestable_elements) - end - - let(:nested_element) do - build_stubbed(:alchemy_element, name: "slide") - end - - let(:content_2) do - mock_model(Content, preview_text: "Content 2", preview_content?: false) - end - before do - allow(nested_element).to receive(:contents) { [content_2] } allow(element).to receive(:all_nested_elements) { [nested_element] } end @@ -699,7 +531,7 @@ module Alchemy end let(:ingredient) do - mock_model(Ingredients::Text, role: "headline", preview_text: "Ingredient 1", preview_ingredient?: false) + mock_model(Ingredients::Text, element: element, role: "intro", preview_text: "Ingredient 1", preview_ingredient?: false) end before do @@ -717,7 +549,7 @@ module Alchemy let(:nested_element) { build_stubbed(:alchemy_element, :with_ingredients) } let(:ingredient) do - mock_model(Ingredients::Text, role: "headline", preview_text: "Ingredient 1", preview_ingredient?: false) + mock_model(Ingredients::Text, role: "intro", preview_text: "Ingredient 1", preview_ingredient?: false) end before do @@ -730,37 +562,6 @@ module Alchemy expect(element.preview_text) end end - - context "when parent element has contents" do - let(:content) do - mock_model(Content, preview_text: "Content 1", preview_content?: false) - end - - before do - allow(element).to receive(:contents) { [content] } - end - - it "returns the preview text from the parent element" do - expect(content).to receive(:preview_text) - expect(element.preview_text) - end - end - - context "when parent element has no contents but nestable element has" do - let(:content) do - mock_model(Content, preview_text: "Content 1", preview_content?: false) - end - - before do - allow(element).to receive(:contents) { [] } - allow(nested_element).to receive(:contents) { [content] } - end - - it "returns the preview text from the first nested element" do - expect(content).to receive(:preview_text) - expect(element.preview_text) - end - end end end @@ -798,85 +599,6 @@ module Alchemy end end - context "retrieving contents, essences and ingredients" do - let(:element) { create(:alchemy_element, :with_contents, name: "news") } - - describe "#ingredient" do - context "with contents" do - let(:essence) { element.content_by_name(:news_headline) } - - it "returns a contents value by name" do - expect(essence).to receive(:ingredient).and_call_original - element.ingredient("news_headline") - end - end - - context "with ingredients" do - let(:element) { create(:alchemy_element, :with_ingredients) } - let(:ingredient) { element.ingredient_by_role(:headline) } - - it "returns a ingredients value by name" do - Alchemy::Deprecation.silenced do - expect(ingredient).to receive(:value).and_call_original - element.ingredient("headline") - end - end - end - end - end - - describe "#update_contents" do - subject { element.update_contents(params) } - - let(:element) { build_stubbed(:alchemy_element) } - let(:content1) { double(:content, id: 1) } - let(:content2) { double(:content, id: 2) } - - before { allow(element).to receive(:contents).and_return([content1]) } - - context "with attributes hash is nil" do - let(:params) { nil } - it { is_expected.to be_truthy } - end - - context "with valid attributes hash" do - let(:params) { { content1.id.to_s => { body: "Title" } } } - - context "when certain content is not part of the attributes hash (cause it was not filled by the user)" do - before do - allow(element).to receive(:contents).and_return([content1, content2]) - end - - it "does not try to update that content" do - expect(content1).to receive(:update_essence).with({ body: "Title" }).and_return(true) - expect(content2).to_not receive(:update_essence) - subject - end - end - - context "with passing validations" do - before do - expect(content1).to receive(:update_essence).with({ body: "Title" }).and_return(true) - end - - it { is_expected.to be_truthy } - - it "does not add errors" do - subject - expect(element.errors).to be_empty - end - end - - context "with failing validations" do - it "adds error and returns false" do - expect(content1).to receive(:update_essence).with({ body: "Title" }).and_return(false) - is_expected.to be_falsey - expect(element.errors).not_to be_empty - end - end - end - end - describe ".after_update" do let(:element) { create(:alchemy_element, page_version: page_version) } @@ -1076,52 +798,6 @@ module Alchemy end end - describe "#richtext_contents_ids" do - subject { element.richtext_contents_ids } - - let(:element) { create(:alchemy_element, :with_contents, name: "text") } - - it { is_expected.to eq(element.content_ids) } - - context "for element with nested elements" do - let!(:element) do - create(:alchemy_element, :with_contents, name: "text") - end - - let!(:nested_element_1) do - create(:alchemy_element, :with_contents, { - name: "text", - parent_element: element, - folded: false, - }) - end - - let!(:nested_element_2) do - create(:alchemy_element, :with_contents, { - name: "text", - parent_element: nested_element_1, - folded: false, - }) - end - - let!(:folded_nested_element_3) do - create(:alchemy_element, :with_contents, { - name: "text", - parent_element: nested_element_1, - folded: true, - }) - end - - it "includes all richtext contents from all expanded descendent elements" do - is_expected.to eq( - element.content_ids + - nested_element_1.content_ids + - nested_element_2.content_ids, - ) - end - end - end - context "with parent element" do let!(:parent_element) { create(:alchemy_element, :with_nestable_elements) } let!(:element) { create(:alchemy_element, name: "slide", parent_element: parent_element) } diff --git a/spec/models/alchemy/essence_audio_spec.rb b/spec/models/alchemy/essence_audio_spec.rb deleted file mode 100644 index a8082996b8..0000000000 --- a/spec/models/alchemy/essence_audio_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Alchemy::EssenceAudio do - let(:attachment) { create(:alchemy_attachment) } - let(:essence) { described_class.new(attachment: attachment) } - - it_behaves_like "an essence" do - let(:ingredient_value) { attachment } - end -end diff --git a/spec/models/alchemy/essence_boolean_spec.rb b/spec/models/alchemy/essence_boolean_spec.rb deleted file mode 100644 index 239796e59f..0000000000 --- a/spec/models/alchemy/essence_boolean_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe EssenceBoolean do - it_behaves_like "an essence" do - let(:essence) { EssenceBoolean.new } - let(:ingredient_value) { true } - end - end -end diff --git a/spec/models/alchemy/essence_date_spec.rb b/spec/models/alchemy/essence_date_spec.rb deleted file mode 100644 index 7aaa8eb442..0000000000 --- a/spec/models/alchemy/essence_date_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe EssenceDate do - let(:essence) { EssenceDate.new } - - it_behaves_like "an essence" do - let(:essence) { EssenceDate.new } - let(:ingredient_value) { Time.current.iso8601 } - end - - describe "#preview_text" do - subject { essence.preview_text } - - context "if no date set" do - it "should return an empty string" do - is_expected.to eq("") - end - end - - context "if date set" do - it "should format the date by i18n" do - essence.date = Time.current - expect(::I18n).to receive(:l).with(essence.date, format: :'alchemy.essence_date') - subject - end - end - end - end -end diff --git a/spec/models/alchemy/essence_file_spec.rb b/spec/models/alchemy/essence_file_spec.rb deleted file mode 100644 index 249901955f..0000000000 --- a/spec/models/alchemy/essence_file_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe EssenceFile do - let(:attachment) { create(:alchemy_attachment) } - let(:essence) { EssenceFile.new(attachment: attachment) } - - it_behaves_like "an essence" do - let(:essence) { EssenceFile.new } - let(:ingredient_value) { attachment } - end - - describe "#attachment_url" do - subject { essence.attachment_url } - - it "returns the download attachment url." do - is_expected.to match(/\/attachment\/#{attachment.id}\/download\/#{attachment.slug}\.#{attachment.suffix}/) - end - - context "without attachment assigned" do - let(:attachment) { nil } - - it { is_expected.to be_nil } - end - end - - describe "#preview_text" do - it "returns the attachment's name as preview text" do - expect(essence.preview_text).to eq(attachment.name) - end - - context "with no attachment assigned" do - it "returns empty string" do - essence.attachment = nil - expect(essence.preview_text).to eq("") - end - end - end - end -end diff --git a/spec/models/alchemy/essence_headline_spec.rb b/spec/models/alchemy/essence_headline_spec.rb deleted file mode 100644 index c924330cee..0000000000 --- a/spec/models/alchemy/essence_headline_spec.rb +++ /dev/null @@ -1,90 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Alchemy::EssenceHeadline do - subject(:essence) do - Alchemy::EssenceHeadline.new( - body: ingredient_value, - level: 2, - size: 3 - ) - end - - let(:ingredient_value) { "A headline" } - - it_behaves_like "an essence" - - describe "#level_options" do - subject { essence.level_options } - - it { is_expected.to eq([["H1", 1], ["H2", 2], ["H3", 3], ["H4", 4], ["H5", 5], ["H6", 6]]) } - - context "when restricted through the essence settings" do - before do - expect(essence).to receive_message_chain(:content, :settings).and_return(levels: [2, 3]) - end - - it { is_expected.to eq([["H2", 2], ["H3", 3]]) } - end - end - - describe "#size_options" do - subject { essence.size_options } - - it { is_expected.to eq([]) } - - context "when enabled through the essence settings" do - before do - expect(essence).to receive_message_chain(:content, :settings).and_return(sizes: [3, 4]) - end - - it { is_expected.to eq([["H3", 3], ["H4", 4]]) } - end - end - - describe "initialization" do - describe "level" do - subject { Alchemy::EssenceHeadline.new.level } - - it { is_expected.to eq(1) } - end - - describe "size" do - let(:content) { build(:alchemy_content) } - let(:essence) { Alchemy::EssenceHeadline.new(content: content) } - subject { essence.size } - - it { is_expected.to be_nil } - - context "when enabled through the essence settings" do - before do - expect(content).to receive(:settings).and_return(sizes: [3, 4]).twice - end - - it { is_expected.to eq(3) } - end - end - end - - describe "creating from a content" do - it "should have the size and level fields filled with correct defaults" do - element = create(:alchemy_element) - - allow(element).to receive(:content_definition_for) do - { - "name" => "headline", - "type" => "EssenceHeadline", - "settings" => { - "sizes" => [3], - "levels" => [2, 3], - }, - }.with_indifferent_access - end - - content = Alchemy::Content.create(element: element, name: "headline") - expect(content.essence.size).to eq(3) - expect(content.essence.level).to eq(2) - end - end -end diff --git a/spec/models/alchemy/essence_html_spec.rb b/spec/models/alchemy/essence_html_spec.rb deleted file mode 100644 index fd4b0c7494..0000000000 --- a/spec/models/alchemy/essence_html_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe EssenceHtml do - let(:essence) { EssenceHtml.new(source: "

hello!

") } - - it_behaves_like "an essence" do - let(:essence) { EssenceHtml.new } - let(:ingredient_value) { "

hello!

" } - end - - describe "#preview_text" do - it "should return html escaped source code" do - expect(essence.preview_text).to eq("<p>hello!</p>") - end - end - end -end diff --git a/spec/models/alchemy/essence_link_spec.rb b/spec/models/alchemy/essence_link_spec.rb deleted file mode 100644 index 3bc8c40ea3..0000000000 --- a/spec/models/alchemy/essence_link_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe EssenceLink do - it_behaves_like "an essence" do - let(:essence) { EssenceLink.new } - let(:ingredient_value) { "http://alchemy-cms.com" } - end - end -end diff --git a/spec/models/alchemy/essence_node_spec.rb b/spec/models/alchemy/essence_node_spec.rb deleted file mode 100644 index 162c3d3785..0000000000 --- a/spec/models/alchemy/essence_node_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Alchemy::EssenceNode, type: :model do - it { is_expected.to belong_to(:ingredient_association).optional.class_name("Alchemy::Node") } - - describe "#ingredient" do - let(:node) { build(:alchemy_node) } - - subject { described_class.new(node: node).ingredient } - - it { is_expected.to eq(node) } - end - - describe "#preview_text" do - let(:node) { build(:alchemy_node) } - - subject { described_class.new(node: node).preview_text } - - it { is_expected.to eq(node.name) } - end -end diff --git a/spec/models/alchemy/essence_page_spec.rb b/spec/models/alchemy/essence_page_spec.rb deleted file mode 100644 index 8df624f7d7..0000000000 --- a/spec/models/alchemy/essence_page_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Alchemy::EssencePage, type: :model do - let(:essence) { build(:alchemy_essence_page) } - let(:page) { essence.page } - - it_behaves_like "an essence" do - let(:ingredient_value) { page } - end - - describe "eager loading" do - let!(:essence_pages) { create_list(:alchemy_essence_page, 2) } - - it "eager loads pages" do - essences = described_class.all.includes(:ingredient_association) - expect(essences[0].association(:ingredient_association)).to be_loaded - end - end -end diff --git a/spec/models/alchemy/essence_picture_spec.rb b/spec/models/alchemy/essence_picture_spec.rb deleted file mode 100644 index 85690e6365..0000000000 --- a/spec/models/alchemy/essence_picture_spec.rb +++ /dev/null @@ -1,103 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe EssencePicture do - around do |example| - RSpec.configure do |config| - config.mock_with :rspec do |mock| - mock.verify_partial_doubles = true - end - end - example.run - RSpec.configure do |config| - config.mock_with :rspec do |mock| - mock.verify_partial_doubles = false - end - end - end - - it_behaves_like "an essence" do - let(:essence) { EssencePicture.new } - let(:ingredient_value) { Picture.new } - end - - describe "eager loading" do - let!(:essence_pictures) { create_list(:alchemy_essence_picture, 2) } - - it "eager loads pictures" do - essences = described_class.all.includes(:ingredient_association) - expect(essences[0].association(:ingredient_association)).to be_loaded - end - end - - it_behaves_like "having picture thumbnails" do - let(:picture) { build(:alchemy_picture) } - let(:record) { build(:alchemy_essence_picture, :with_content, picture: picture) } - end - - it "should convert newlines in caption into
s" do - essence = EssencePicture.new(caption: "hello\nkitty") - essence.save! - expect(essence.caption).to eq("hello
kitty") - end - - describe "#preview_text" do - let(:picture) { mock_model(Picture, name: "Cute Cat Kittens") } - let(:essence) { EssencePicture.new } - - it "should return the pictures name as preview text" do - allow(essence).to receive(:picture).and_return(picture) - expect(essence.preview_text).to eq("Cute Cat Kittens") - end - - context "with no picture assigned" do - it "returns empty string" do - expect(essence.preview_text).to eq("") - end - end - end - - describe "#serialized_ingredient" do - let(:content) do - Content.new - end - - let(:picture) do - mock_model Picture, - name: "Cute Cat Kittens", - urlname: "cute-cat-kittens", - security_token: "kljhgfd", - default_render_format: "jpg" - end - - let(:essence) do - EssencePicture.new(content: content, picture: picture) - end - - it "returns the url to render the picture" do - expect(essence).to receive(:picture_url).with(content.settings) - essence.serialized_ingredient - end - - context "with image settings set as content settings" do - let(:settings) do - { - size: "150x150", - format: "png", - } - end - - before do - expect(content).to receive(:settings) { settings } - end - - it "returns the url with cropping and resizing options" do - expect(essence).to receive(:picture_url).with(settings) - essence.serialized_ingredient - end - end - end - end -end diff --git a/spec/models/alchemy/essence_picture_view_spec.rb b/spec/models/alchemy/essence_picture_view_spec.rb deleted file mode 100644 index 4c5598f6ec..0000000000 --- a/spec/models/alchemy/essence_picture_view_spec.rb +++ /dev/null @@ -1,332 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe Alchemy::EssencePictureView, type: :model do - include Capybara::RSpecMatchers - - let(:image) do - File.new(File.expand_path("../../fixtures/image.png", __dir__)) - end - - let(:picture) do - stub_model Alchemy::Picture, - image_file_format: "png", - image_file: image - end - - let(:essence_picture) do - stub_model Alchemy::EssencePicture, - picture: picture, - caption: "This is a cute cat" - end - - let(:content) do - stub_model Alchemy::Content, - name: "image", - essence_type: "EssencePicture", - essence: essence_picture - end - - let(:picture_url) { "/pictures/1/image.png" } - - before do - allow(picture).to receive(:url) { picture_url } - end - - describe "DEFAULT_OPTIONS" do - it do - expect(Alchemy::EssencePictureView::DEFAULT_OPTIONS). - to be_a(HashWithIndifferentAccess) - end - end - - context "with caption" do - let(:options) do - {} - end - - let(:html_options) do - {} - end - - subject(:view) do - Alchemy::EssencePictureView.new(content, options, html_options).render - end - - it "should enclose the image in a
element" do - expect(view).to have_selector("figure img") - end - - it "should show the caption" do - expect(view).to have_selector("figure figcaption") - expect(view).to have_content("This is a cute cat") - end - - it "does not pass default options to picture url" do - expect(essence_picture).to receive(:picture_url).with({}) { picture_url } - view - end - - context "but disabled in the options" do - let(:options) do - { show_caption: false } - end - - it "should not enclose the image in a
element" do - expect(view).to_not have_selector("figure img") - end - - it "should not show the caption" do - expect(view).to_not have_selector("figure figcaption") - expect(view).to_not have_content("This is a cute cat") - end - end - - context "but disabled in the content settings" do - before do - allow(content).to receive(:settings).and_return({ show_caption: false }) - end - - it "should not enclose the image in a
element" do - expect(view).to_not have_selector("figure img") - end - - it "should not show the caption" do - expect(view).to_not have_selector("figure figcaption") - expect(view).to_not have_content("This is a cute cat") - end - - context "but enabled in the options hash" do - let(:options) { { show_caption: true } } - - it "should enclose the image in a
element" do - expect(view).to have_selector("figure img") - end - - it "should show the caption" do - expect(view).to have_selector("figure figcaption") - expect(view).to have_content("This is a cute cat") - end - end - end - - context "and essence with css class" do - before do - essence_picture.css_class = "left" - end - - it "should have the class on the
element" do - expect(view).to have_selector("figure.left img") - end - - it "should not have the class on the element" do - expect(view).not_to have_selector("figure img.left") - end - end - - context "and css class in the html_options" do - before do - html_options[:class] = "right" - end - - it "should have the class from the html_options on the
element" do - expect(view).to have_selector("figure.right img") - end - - it "should not have the class from the essence on the
element" do - expect(view).not_to have_selector("figure.left img") - end - - it "should not have the class from the html_options on the element" do - expect(view).not_to have_selector("figure img.right") - end - end - end - - context "with link" do - let(:options) do - {} - end - - subject(:view) do - essence_picture.link = "/home" - Alchemy::EssencePictureView.new(content, options).render - end - - it "should enclose the image in a link tag" do - expect(view).to have_selector('a[href="/home"] img') - end - - context "but disabled link option" do - before do - options[:disable_link] = true - end - - it "should not enclose the image in a link tag" do - expect(view).not_to have_selector("a img") - end - end - end - - context "with multiple instances" do - let(:options) do - {} - end - - subject(:picture_view) do - Alchemy::EssencePictureView.new(content, options) - end - - it "does not overwrite DEFAULT_OPTIONS" do - Alchemy::EssencePictureView.new(content, { my_custom_option: true }) - expect(picture_view.options).to_not have_key(:my_custom_option) - end - end - - context "with srcset content setting" do - before do - allow(content).to receive(:settings) do - { srcset: srcset } - end - end - - subject(:view) do - Alchemy::EssencePictureView.new(content).render - end - - let(:srcset) do - [] - end - - it "does not pass srcset option to picture_url" do - expect(essence_picture).to receive(:picture_url).with({}) { picture_url } - view - end - - context "when only width or width and height are set" do - let(:srcset) do - %w(1024x768 800x) - end - - it "adds srcset attribute including image url and width for each size" do - url1 = essence_picture.picture_url(size: "1024x768") - url2 = essence_picture.picture_url(size: "800x") - - expect(view).to have_selector("img[srcset=\"#{url1} 1024w, #{url2} 800w\"]") - end - end - - context "when only height is set" do - let(:srcset) do - %w(x768 x600) - end - - it "adds srcset attribute including image url and height for each size" do - url1 = essence_picture.picture_url(size: "x768") - url2 = essence_picture.picture_url(size: "x600") - - expect(view).to have_selector("img[srcset=\"#{url1} 768h, #{url2} 600h\"]") - end - end - end - - context "with no srcset content setting" do - subject(:view) do - Alchemy::EssencePictureView.new(content).render - end - - it "image tag has no srcset attribute" do - expect(view).not_to have_selector("img[srcset]") - end - end - - context "with sizes content setting" do - before do - allow(content).to receive(:settings) do - { sizes: sizes } - end - end - - subject(:view) do - Alchemy::EssencePictureView.new(content).render - end - - let(:sizes) do - [ - "(max-width: 1023px) 100vh", - "(min-width: 1024px) 33.333vh", - ] - end - - it "does not pass sizes option to picture_url" do - expect(essence_picture).to receive(:picture_url).with({}) { picture_url } - view - end - - it "adds sizes attribute for each size" do - expect(view).to have_selector("img[sizes=\"#{sizes[0]}, #{sizes[1]}\"]") - end - end - - context "with no sizes content setting" do - subject(:view) do - Alchemy::EssencePictureView.new(content).render - end - - it "image tag has no sizes attribute" do - expect(view).not_to have_selector("img[sizes]") - end - end - - describe "alt text" do - subject(:view) do - Alchemy::EssencePictureView.new(content, {}, html_options).render - end - - let(:html_options) { {} } - - context "essence having alt text stored" do - let(:essence_picture) do - stub_model Alchemy::EssencePicture, - picture: picture, - alt_tag: "A cute cat" - end - - it "uses this as image alt text" do - expect(view).to have_selector('img[alt="A cute cat"]') - end - end - - context "essence not having alt text stored" do - context "but passed as html option" do - let(:html_options) { { alt: "Cute kittens" } } - - it "uses this as image alt text" do - expect(view).to have_selector('img[alt="Cute kittens"]') - end - end - - context "and not passed as html option" do - context "with name on the picture" do - let(:picture) do - stub_model Alchemy::Picture, - image_file_format: "png", - image_file: image, - name: "cute_kitty-cat" - end - - it "uses a humanized picture name as alt text" do - expect(view).to have_selector('img[alt="Cute kitty-cat"]') - end - end - - context "and no name on the picture" do - it "has no alt text" do - expect(view).to_not have_selector("img[alt]") - end - end - end - end - end -end diff --git a/spec/models/alchemy/essence_richtext_spec.rb b/spec/models/alchemy/essence_richtext_spec.rb deleted file mode 100644 index 289adb80b5..0000000000 --- a/spec/models/alchemy/essence_richtext_spec.rb +++ /dev/null @@ -1,62 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe EssenceRichtext do - let(:element) { create(:alchemy_element, name: "article") } - let(:content) { Alchemy::Content.new(name: "text", element: element) } - let(:essence) do - Alchemy::EssenceRichtext.new( - content: content, - body: "

Hello!

Welcome to Peters Petshop.

" - ) - end - - context "without a content" do - let(:essence) do - Alchemy::EssenceRichtext.new( - body: "

Hello!

Welcome to Peters Petshop.

" - ) - end - - it "can still be created with no odd error" do - expect { essence.save! }.not_to raise_exception - end - end - - it_behaves_like "an essence" do - let(:essence) { EssenceRichtext.new(content: content) } - let(:ingredient_value) { "

Hello!

Welcome to Peters Petshop.

" } - end - - it "should save a HTML tag free version of body column" do - essence.save - expect(essence.stripped_body).to eq("Hello!Welcome to Peters Petshop.") - end - - it "should save a sanitized version of body column" do - essence.save - expect(essence.sanitized_body).to eq("

Hello!

Welcome to Peters Petshop.

") - end - - context "when class is not part of the allowed attributes" do - let(:element) { create(:alchemy_element, name: "text") } - let(:content) { Alchemy::Content.new(name: "text", element: element) } - - it "should save a sanitized version of body column" do - essence.save - expect(essence.sanitized_body).to eq("Hello!

Welcome to Peters Petshop.

") - end - end - - it "should save a HTML tag free version of body column" do - essence.save - expect(essence.stripped_body).to eq("Hello!Welcome to Peters Petshop.") - end - - it "has tinymce enabled" do - expect(essence.has_tinymce?).to eq(true) - end - end -end diff --git a/spec/models/alchemy/essence_select_spec.rb b/spec/models/alchemy/essence_select_spec.rb deleted file mode 100644 index 7a2e404b69..0000000000 --- a/spec/models/alchemy/essence_select_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe EssenceSelect do - it_behaves_like "an essence" do - let(:essence) { EssenceSelect.new } - let(:ingredient_value) { "select value" } - end - end -end diff --git a/spec/models/alchemy/essence_text_spec.rb b/spec/models/alchemy/essence_text_spec.rb deleted file mode 100644 index d770e4020b..0000000000 --- a/spec/models/alchemy/essence_text_spec.rb +++ /dev/null @@ -1,112 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe EssenceText do - let(:essence) { EssenceText.new } - let(:ingredient_value) { "Lorem ipsum" } - - it_behaves_like "an essence" do - let(:essence) { EssenceText.new } - let(:ingredient_value) { "Lorem ipsum" } - end - - describe "#preview_text" do - before do - ingredient_column = essence.ingredient_column - essence.send("#{ingredient_column}=", ingredient_value) - end - - it "should return a preview text" do - expect(essence.preview_text).to eq(ingredient_value.to_s) - end - - context "with given maxlength" do - it "should return as much beginning characters as defined with maxlength" do - expect(essence.preview_text(2)).to eq(ingredient_value.to_s[0..1]) - end - end - - context "with another preview_text_column defined" do - before do - allow(essence).to receive(:title).and_return("Title column") - allow(essence).to receive(:preview_text_column).and_return(:title) - end - - it "should use this column as preview text method" do - expect(essence.preview_text).to eq("Title column") - end - end - end - - describe "#open_link_in_new_window?" do - let(:essence) { EssenceText.new } - subject { essence.open_link_in_new_window? } - - context "essence responds to link_taget" do - context 'if link_target attribute is set to "blank"' do - before { essence.link_target = "blank" } - - it "should return true" do - expect(subject).to eq(true) - end - end - - context 'if link_target attribute is not "blank"' do - it "should return false" do - expect(subject).to eq(false) - end - end - end - end - - describe "validations" do - describe "format" do - context "given a regex string" do - before do - allow(essence).to receive(:definition).and_return({"validate" => [{"format" => /\Ahttps:\/\/[\S]+/}]}) - end - - context "when ingredient string does not match the given regex" do - before { essence.update(essence.ingredient_column.to_sym => "http://alchemy-cms.com") } - - it "should not be valid" do - expect(essence).to_not be_valid - end - end - - context "when ingredient string matches the given regex" do - before { essence.update(essence.ingredient_column.to_sym => "https://alchemy-cms.com") } - - it "should be valid" do - expect(essence).to be_valid - end - end - end - - context "given a key from the config`s format_matcher list" do - before do - allow(essence).to receive(:definition).and_return({"validate" => [{"format" => "email"}]}) - end - - context "when ingredient string does not match the given format matcher" do - before { essence.update(essence.ingredient_column.to_sym => ingredient_value) } - - it "should not be valid" do - expect(essence).to_not be_valid - end - end - - context "when ingredient string matches the given format matcher" do - before { essence.update(essence.ingredient_column.to_sym => "email@email.com") } - - it "should be valid" do - expect(essence).to be_valid - end - end - end - end - end - end -end diff --git a/spec/models/alchemy/essence_video_spec.rb b/spec/models/alchemy/essence_video_spec.rb deleted file mode 100644 index 1843e9dde8..0000000000 --- a/spec/models/alchemy/essence_video_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Alchemy::EssenceVideo do - let(:attachment) { create(:alchemy_attachment) } - let(:essence) { described_class.new(attachment: attachment) } - - it_behaves_like "an essence" do - let(:ingredient_value) { attachment } - end -end diff --git a/spec/models/alchemy/node_spec.rb b/spec/models/alchemy/node_spec.rb index c74bc6aeb0..70b4c7d58c 100644 --- a/spec/models/alchemy/node_spec.rb +++ b/spec/models/alchemy/node_spec.rb @@ -4,7 +4,7 @@ module Alchemy describe Node do - it { is_expected.to have_many(:essence_nodes) } + it { is_expected.to have_many(:node_ingredients) } it { is_expected.to respond_to(:menu_type) } it "is only valid with language and name given" do @@ -22,7 +22,7 @@ module Alchemy end context "with current language present" do - let!(:root_node) { create(:alchemy_node) } + let!(:root_node) { create(:alchemy_node) } let!(:child_node) { create(:alchemy_node, parent_id: root_node.id) } it "returns root nodes from current language" do @@ -126,11 +126,10 @@ module Alchemy context "if there are essence nodes present" do let(:node) { create(:alchemy_node) } let(:page) { create(:alchemy_page, :layoutpage, page_layout: :footer) } - let(:element) { create(:alchemy_element, name: "menu", page: page) } - let(:content) { create(:alchemy_content, name: "menu", element: element) } + let(:element) { create(:alchemy_element, name: "menu", page_version: page.draft_version) } before do - node.essence_nodes.create(content: content) + create(:alchemy_ingredient_node, element: element, related_object: node) end it "does not destroy the node but adds an error" do diff --git a/spec/models/alchemy/page_spec.rb b/spec/models/alchemy/page_spec.rb index 3042315a4c..07716a5858 100644 --- a/spec/models/alchemy/page_spec.rb +++ b/spec/models/alchemy/page_spec.rb @@ -1,3 +1,4 @@ +# encoding: utf-8 # frozen_string_literal: true require "rails_helper" @@ -318,7 +319,7 @@ class AnotherUrlPathClass; end before do create(:alchemy_page, :public, :locked, locked_by: 53) # This page must not be part of the collection allow(user.class).to receive(:primary_key) - .and_return("id") + .and_return("id") end it "should return the correct page collection blocked by a certain user" do @@ -331,7 +332,7 @@ class AnotherUrlPathClass; end before do allow(user.class).to receive(:primary_key) - .and_return("user_id") + .and_return("user_id") end it "should return the correct page collection blocked by a certain user" do @@ -446,9 +447,9 @@ class AnotherUrlPathClass; end before do page = create(:alchemy_page) allow(page).to receive(:definition).and_return({ - "name" => "standard", - "elements" => ["headline"], - "autogenerate" => ["headline"], + "name" => "standard", + "elements" => ["headline"], + "autogenerate" => ["headline"], }) end @@ -685,24 +686,38 @@ class AnotherUrlPathClass; end let!(:element_3) { create(:alchemy_element, name: "column_headline", page: page, page_version: page.draft_version) } before do - allow(Element).to receive(:definitions).and_return([ - { - "name" => "column_headline", - "amount" => 3, - "contents" => [{ "name" => "headline", "type" => "EssenceText" }], - }, - { - "name" => "unique_headline", - "unique" => true, - "amount" => 3, - "contents" => [{ "name" => "headline", "type" => "EssenceText" }], - }, - ]) - allow(PageLayout).to receive(:get).and_return({ - "name" => "columns", - "elements" => ["column_headline", "unique_headline"], - "autogenerate" => ["unique_headline", "column_headline", "column_headline", "column_headline"], - }) + allow(Element).to receive(:definitions) do + [ + { + "name" => "column_headline", + "amount" => 3, + "ingredients" => [ + { + "role" => "headline", + "type" => "Text", + }, + ], + }, + { + "name" => "unique_headline", + "unique" => true, + "amount" => 3, + "ingredients" => [ + { + "role" => "headline", + "type" => "Text", + }, + ], + }, + ] + end + allow(PageLayout).to receive(:get) do + { + "name" => "columns", + "elements" => ["column_headline", "unique_headline"], + "autogenerate" => ["unique_headline", "column_headline", "column_headline", "column_headline"], + } + end end it "should be readable" do @@ -1137,7 +1152,7 @@ class AnotherUrlPathClass; end children: [ build(:alchemy_page), build(:alchemy_page, name: "child with children", children: [build(:alchemy_page)]), - ] + ], ) end @@ -1183,8 +1198,8 @@ def copy_children_to(new_parent) next if child == new_parent new_child = Page.copy(child, { - language_id: new_parent.language_id, - language_code: new_parent.language_code, + language_id: new_parent.language_id, + language_code: new_parent.language_code, }) new_child.move_to_child_of(new_parent) child.copy_children_to(new_child) unless child.children.blank? @@ -1244,10 +1259,10 @@ def copy_children_to(new_parent) it "should copy the source page with the given name to the new parent" do expect(Page).to receive(:copy).with(source, { - parent: new_parent, - language: new_parent.language, - name: page_name, - title: page_name, + parent: new_parent, + language: new_parent.language, + name: page_name, + title: page_name, }) subject end @@ -1272,10 +1287,10 @@ def copy_children_to(new_parent) it "copies the source page with the given name" do expect(Page).to receive(:copy).with(source, { - parent: nil, - language: nil, - name: page_name, - title: page_name, + parent: nil, + language: nil, + name: page_name, + title: page_name, }) subject end @@ -1998,62 +2013,6 @@ def copy_children_to(new_parent) end end - describe "#richtext_contents_ids" do - let!(:page) { create(:alchemy_page) } - - let!(:expanded_element) do - create :alchemy_element, :with_contents, - name: "article", - page_version: page.draft_version, - folded: false - end - - let!(:folded_element) do - create :alchemy_element, :with_contents, - name: "article", - page_version: page.draft_version, - folded: true - end - - subject(:richtext_contents_ids) { page.richtext_contents_ids } - - it "returns content ids for all expanded elements that have tinymce enabled" do - expanded_rtf_contents = expanded_element.contents.essence_richtexts - expect(richtext_contents_ids).to eq(expanded_rtf_contents.pluck(:id)) - folded_rtf_content = folded_element.contents.essence_richtexts.first - expect(richtext_contents_ids).to_not include(folded_rtf_content.id) - end - - context "with nested elements" do - let!(:nested_expanded_element) do - create :alchemy_element, :with_contents, - name: "article", - page_version: page.draft_version, - parent_element: expanded_element, - folded: false - end - - let!(:nested_folded_element) do - create :alchemy_element, :with_contents, - name: "article", - page_version: page.draft_version, - parent_element: folded_element, - folded: true - end - - it "returns content ids for all expanded nested elements that have tinymce enabled" do - expanded_rtf_contents = expanded_element.contents.essence_richtexts - nested_expanded_rtf_contents = nested_expanded_element.contents.essence_richtexts - rtf_content_ids = expanded_rtf_contents.pluck(:id) + nested_expanded_rtf_contents.pluck(:id) - expect(richtext_contents_ids.sort).to eq(rtf_content_ids) - - nested_folded_rtf_content = nested_folded_element.contents.essence_richtexts.first - - expect(richtext_contents_ids).to_not include(nested_folded_rtf_content.id) - end - end - end - describe "#richtext_ingredients_ids" do let!(:page) { create(:alchemy_page) } diff --git a/spec/models/alchemy/page_version_spec.rb b/spec/models/alchemy/page_version_spec.rb index 45f7b3c4d8..b09c8c9ddc 100644 --- a/spec/models/alchemy/page_version_spec.rb +++ b/spec/models/alchemy/page_version_spec.rb @@ -127,9 +127,9 @@ end describe "dependent element destruction" do - let!(:parent_element) { create(:alchemy_element, :with_nestable_elements, :with_contents) } + let!(:parent_element) { create(:alchemy_element, :with_nestable_elements, :with_ingredients) } let!(:nested_element) { parent_element.nested_elements.first } - let!(:normal_element) { create(:alchemy_element, :with_contents) } + let!(:normal_element) { create(:alchemy_element, :with_ingredients) } let(:page_version) { create(:alchemy_page_version) } @@ -140,10 +140,7 @@ it "deletes all elements along with the page version" do page_version.destroy! expect(Alchemy::Element.count).to be_zero - expect(Alchemy::Content.count).to be_zero - expect(Alchemy::EssenceText.count).to be_zero - expect(Alchemy::EssencePicture.count).to be_zero - expect(Alchemy::EssenceRichtext.count).to be_zero + expect(Alchemy::Ingredient.count).to be_zero end end diff --git a/spec/models/alchemy/picture_spec.rb b/spec/models/alchemy/picture_spec.rb index 50b3be5072..c1f668e049 100644 --- a/spec/models/alchemy/picture_spec.rb +++ b/spec/models/alchemy/picture_spec.rb @@ -177,12 +177,8 @@ module Alchemy describe "#destroy" do context "a picture that is assigned in an essence" do - let(:essence_picture) { EssencePicture.create } - let(:picture) { create :alchemy_picture } - - before do - essence_picture.update_columns(picture_id: picture.id) - end + let(:picture) { create(:alchemy_picture) } + let!(:picture_ingredient) { create(:alchemy_ingredient_picture, related_object: picture) } it "should raise error message" do expect { picture.destroy }.to raise_error PictureInUseError @@ -443,16 +439,15 @@ module Alchemy end describe "after update" do - context "assigned to contents" do + context "assigned to ingredient" do let(:picture) { create(:alchemy_picture) } - let(:content) do - create(:alchemy_content, :essence_picture) + let(:ingredient) do + create(:alchemy_ingredient_picture, related_object: picture) end before do - content.essence.update(picture: picture) - content.element.update_column(:updated_at, 3.hours.ago) + ingredient.element.update_column(:updated_at, 3.hours.ago) end it "touches elements" do diff --git a/spec/models/dummy_model_spec.rb b/spec/models/dummy_model_spec.rb deleted file mode 100644 index b495b4913c..0000000000 --- a/spec/models/dummy_model_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "A User-defined Essence" do - describe DummyModel do - it_behaves_like "an essence" do - let(:essence) { DummyModel.new } - let(:ingredient_value) { "Some String" } - end - end -end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 1c6d86bca3..6d8c9ac1a8 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -5,7 +5,7 @@ # Configure Rails Environment ENV["RAILS_ENV"] = "test" -require_relative("dummy/config/environment.rb") +require_relative("dummy/config/environment") require "capybara/rails" require "capybara-screenshot/rspec" @@ -19,7 +19,6 @@ require "alchemy/seeder" require "alchemy/test_support" require "alchemy/test_support/config_stubbing" -require "alchemy/test_support/essence_shared_examples" require "alchemy/test_support/having_crop_action_examples" require "alchemy/test_support/having_picture_thumbnails_examples" require "alchemy/test_support/shared_dom_ids_examples" @@ -29,10 +28,10 @@ require "alchemy/test_support/shared_contexts" require "alchemy/test_support/shared_uploader_examples" -require_relative "support/calculation_examples.rb" -require_relative "support/hint_examples.rb" -require_relative "support/transformation_examples.rb" -require_relative "support/capybara_helpers.rb" +require_relative "support/calculation_examples" +require_relative "support/hint_examples" +require_relative "support/transformation_examples" +require_relative "support/capybara_helpers" require_relative "support/custom_news_elements_finder" ActionMailer::Base.delivery_method = :test diff --git a/spec/requests/alchemy/admin/contents_controller_spec.rb b/spec/requests/alchemy/admin/contents_controller_spec.rb deleted file mode 100644 index 7086dbda2b..0000000000 --- a/spec/requests/alchemy/admin/contents_controller_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -module Alchemy - describe Admin::ContentsController do - before do - authorize_user(:as_admin) - end - - context "with element_id parameter" do - describe "#create" do - let(:element) { create(:alchemy_element, name: "headline") } - - it "creates a content from name" do - expect { - post admin_contents_path(content: {element_id: element.id, name: "headline"}, format: :js) - }.to change { Alchemy::Content.count }.by(1) - end - end - end - end -end diff --git a/spec/routing/api_routing_spec.rb b/spec/routing/api_routing_spec.rb index 29ade92dfd..b0e5bfade9 100644 --- a/spec/routing/api_routing_spec.rb +++ b/spec/routing/api_routing_spec.rb @@ -7,7 +7,7 @@ describe "for pages" do it "has route to show all pages." do - expect({get: "/api/pages.json"}).to route_to( + expect({ get: "/api/pages.json" }).to route_to( controller: "alchemy/api/pages", action: "index", format: "json", @@ -16,7 +16,7 @@ context "with missing format" do it "defaults to json." do - expect({get: "/api/pages"}).to route_to( + expect({ get: "/api/pages" }).to route_to( controller: "alchemy/api/pages", action: "index", format: "json", @@ -25,7 +25,7 @@ end it "has route to show a page by urlname." do - expect({get: "/api/pages/a-page.json"}).to route_to( + expect({ get: "/api/pages/a-page.json" }).to route_to( controller: "alchemy/api/pages", action: "show", urlname: "a-page", @@ -34,7 +34,7 @@ end it "has route to show a page by nested urlname." do - expect({get: "/api/pages/nested/a-page"}).to route_to( + expect({ get: "/api/pages/nested/a-page" }).to route_to( controller: "alchemy/api/pages", action: "show", urlname: "nested/a-page", @@ -44,7 +44,7 @@ context "with admin namespace" do it "routes to api pages controller." do - expect({get: "/api/admin/pages/8"}).to route_to( + expect({ get: "/api/admin/pages/8" }).to route_to( controller: "alchemy/api/pages", action: "show", id: "8", @@ -56,7 +56,7 @@ describe "for elements" do it "has route to show all elements." do - expect({get: "/api/elements.json"}).to route_to( + expect({ get: "/api/elements.json" }).to route_to( controller: "alchemy/api/elements", action: "index", format: "json", @@ -65,7 +65,7 @@ context "with missing format" do it "defaults to json." do - expect({get: "/api/elements"}).to route_to( + expect({ get: "/api/elements" }).to route_to( controller: "alchemy/api/elements", action: "index", format: "json", @@ -74,7 +74,7 @@ end it "has route to show all elements for page id." do - expect({get: "/api/pages/1/elements.json"}).to route_to( + expect({ get: "/api/pages/1/elements.json" }).to route_to( controller: "alchemy/api/elements", action: "index", page_id: "1", @@ -83,7 +83,7 @@ end it "has route to show all elements for page id and name." do - expect({get: "/api/pages/1/elements/article.json"}).to route_to( + expect({ get: "/api/pages/1/elements/article.json" }).to route_to( controller: "alchemy/api/elements", action: "index", page_id: "1", @@ -93,7 +93,7 @@ end it "has route to show an element." do - expect({get: "/api/elements/1.json"}).to route_to( + expect({ get: "/api/elements/1.json" }).to route_to( controller: "alchemy/api/elements", action: "show", id: "1", @@ -101,52 +101,4 @@ ) end end - - describe "for contents" do - it "has route to show all contents." do - expect({get: "/api/contents.json"}).to route_to( - controller: "alchemy/api/contents", - action: "index", - format: "json", - ) - end - - context "with missing format" do - it "defaults to json." do - expect({get: "/api/contents"}).to route_to( - controller: "alchemy/api/contents", - action: "index", - format: "json", - ) - end - end - - it "has route to show all contents for element id." do - expect({get: "/api/elements/1/contents.json"}).to route_to( - controller: "alchemy/api/contents", - action: "index", - element_id: "1", - format: "json", - ) - end - - it "has route to show all contents for element id and name." do - expect({get: "/api/elements/1/contents/headline.json"}).to route_to( - controller: "alchemy/api/contents", - action: "show", - element_id: "1", - name: "headline", - format: "json", - ) - end - - it "has route to show a content." do - expect({get: "/api/contents/1.json"}).to route_to( - controller: "alchemy/api/contents", - action: "show", - id: "1", - format: "json", - ) - end - end end diff --git a/spec/serializers/alchemy/element_serializer_spec.rb b/spec/serializers/alchemy/element_serializer_spec.rb index 1251d8733b..c59fc4082a 100644 --- a/spec/serializers/alchemy/element_serializer_spec.rb +++ b/spec/serializers/alchemy/element_serializer_spec.rb @@ -10,7 +10,6 @@ it "includes all attributes" do json = JSON.parse(subject) expect(json).to eq( - "content_ids" => [], "created_at" => element.created_at.strftime("%FT%T.%LZ"), "display_name" => element.display_name_with_preview_text, "dom_id" => element.dom_id, diff --git a/spec/services/alchemy/delete_elements_spec.rb b/spec/services/alchemy/delete_elements_spec.rb index 674d5a8bdf..f951d41b16 100644 --- a/spec/services/alchemy/delete_elements_spec.rb +++ b/spec/services/alchemy/delete_elements_spec.rb @@ -3,18 +3,15 @@ require "rails_helper" RSpec.describe Alchemy::DeleteElements do - let!(:parent_element) { create(:alchemy_element, :with_nestable_elements, :with_contents) } + let!(:parent_element) { create(:alchemy_element, :with_nestable_elements, :with_ingredients) } let!(:nested_element) { parent_element.nested_elements.first } - let!(:normal_element) { create(:alchemy_element, :with_contents, tag_names: ["Zero"]) } + let!(:normal_element) { create(:alchemy_element, :with_ingredients, tag_names: ["Zero"]) } before do nested_element.tag_names = ["Cool"] nested_element.save! expect(Alchemy::Element.count).not_to be_zero - expect(Alchemy::Content.count).not_to be_zero - expect(Alchemy::EssenceText.count).not_to be_zero - expect(Alchemy::EssencePicture.count).not_to be_zero - expect(Alchemy::EssenceRichtext.count).not_to be_zero + expect(Alchemy::Ingredient.count).not_to be_zero expect(Gutentag::Tagging.count).not_to be_zero end @@ -26,10 +23,7 @@ it "destroys all elements" do subject expect(Alchemy::Element.count).to be_zero - expect(Alchemy::Content.count).to be_zero - expect(Alchemy::EssenceText.count).to be_zero - expect(Alchemy::EssencePicture.count).to be_zero - expect(Alchemy::EssenceRichtext.count).to be_zero + expect(Alchemy::Ingredient.count).to be_zero expect(Gutentag::Tagging.count).to be_zero end @@ -39,10 +33,7 @@ it "works" do subject expect(Alchemy::Element.count).to be_zero - expect(Alchemy::Content.count).to be_zero - expect(Alchemy::EssenceText.count).to be_zero - expect(Alchemy::EssencePicture.count).to be_zero - expect(Alchemy::EssenceRichtext.count).to be_zero + expect(Alchemy::Ingredient.count).to be_zero expect(Gutentag::Tagging.count).to be_zero end end @@ -57,10 +48,7 @@ it "works" do subject expect(Alchemy::Element.count).to be_zero - expect(Alchemy::Content.count).to be_zero - expect(Alchemy::EssenceText.count).to be_zero - expect(Alchemy::EssencePicture.count).to be_zero - expect(Alchemy::EssenceRichtext.count).to be_zero + expect(Alchemy::Ingredient.count).to be_zero expect(Gutentag::Tagging.count).to be_zero end end diff --git a/spec/services/alchemy/duplicate_element_spec.rb b/spec/services/alchemy/duplicate_element_spec.rb index 4e950dc707..7f4b1cc89f 100644 --- a/spec/services/alchemy/duplicate_element_spec.rb +++ b/spec/services/alchemy/duplicate_element_spec.rb @@ -4,13 +4,13 @@ RSpec.describe Alchemy::DuplicateElement do let(:element) do - create(:alchemy_element, :with_contents, tag_list: "red, yellow") + create(:alchemy_element, :with_ingredients, tag_list: "red, yellow") end let(:differences) { {} } subject { described_class.new(element).call(differences) } it "should not create contents from scratch" do - expect(subject.contents.count).to eq(element.contents.count) + expect(subject.ingredients.count).to eq(element.ingredients.count) end context "with differences" do @@ -22,9 +22,9 @@ end end - it "should make copies of all contents of source" do - expect(subject.contents).not_to be_empty - expect(subject.contents.pluck(:id)).not_to eq(element.contents.pluck(:id)) + it "should make copies of all ingredients of source" do + expect(subject.ingredients).not_to be_empty + expect(subject.ingredients.pluck(:id)).not_to eq(element.ingredients.pluck(:id)) end it "the copy should include source element tags" do @@ -33,7 +33,7 @@ context "with nested elements" do let(:element) do - create(:alchemy_element, :with_contents, :with_nestable_elements, { + create(:alchemy_element, :with_ingredients, :with_nestable_elements, { tag_list: "red, yellow", page: create(:alchemy_page), }) diff --git a/spec/support/capybara_helpers.rb b/spec/support/capybara_helpers.rb index de669bb7e2..93375105f5 100644 --- a/spec/support/capybara_helpers.rb +++ b/spec/support/capybara_helpers.rb @@ -16,8 +16,10 @@ def select2(value, options) end within_entire_page do - page.find("div.select2-result-label", - text: /#{Regexp.escape(value)}/i, match: :prefer_exact).click + page.find( + "div.select2-result-label", + text: /#{Regexp.escape(value)}/i, match: :prefer_exact, + ).click end end @@ -27,9 +29,8 @@ def select2_search(value, options) within label.first(:xpath, ".//..") do options[:from] = "##{find(".select2-container")["id"]}" end - elsif options[:element_id] && options[:content_name] - container_id = find("#element_#{options[:element_id]} [data-content-name='#{options[:content_name]}'] .select2-container" - )["id"] + elsif options[:element_id] && options[:ingredient_role] + container_id = find("#element_#{options[:element_id]} [data-ingredient-role='#{options[:ingredient_role]}'] .select2-container")["id"] options[:from] = "##{container_id}" end diff --git a/spec/views/alchemy/admin/essence_pictures/edit_spec.rb b/spec/views/alchemy/admin/essence_pictures/edit_spec.rb deleted file mode 100644 index 558a3c6372..0000000000 --- a/spec/views/alchemy/admin/essence_pictures/edit_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/admin/essence_pictures/edit.html.erb" do - let(:image) do - fixture_file_upload( - File.expand_path("../../../../fixtures/500x500.png", __dir__), - "image/png" - ) - end - - let(:picture) do - create(:alchemy_picture, { - image_file: image, - name: "img", - image_file_name: "img.png", - }) - end - - let(:content) { Alchemy::Content.new(id: 1) } - let(:essence) { Alchemy::EssencePicture.new(id: 1, content: content, picture: picture) } - - before do - view.extend Alchemy::Admin::FormHelper - view.instance_variable_set(:@essence_picture, essence) - view.instance_variable_set(:@content, content) - end - - it "displays render_size selection if sizes present" do - allow(content).to receive(:settings).and_return({ - sizes: [ - ["Medium, 400x400", "400x400"], - ["Small, 200x200", "200x200"], - ], - }) - - render - - expect(rendered).to have_selector(".input.essence_picture_render_size") - end - - it "does not display render_size selection if srcset present" do - # As the same sizes setting is used in another way here - allow(content).to receive(:settings).and_return({ - sizes: ["(min-width: 600px) 600px", "100vw"], - srcset: ["200x100", "400x200", "600x300"], - }) - - render - - expect(rendered).to_not have_selector(".input.essence_picture_render_size") - end -end diff --git a/spec/views/essences/essence_audio_editor_spec.rb b/spec/views/essences/essence_audio_editor_spec.rb deleted file mode 100644 index 90baf6f4c4..0000000000 --- a/spec/views/essences/essence_audio_editor_spec.rb +++ /dev/null @@ -1,71 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_audio_editor" do - let(:attachment) { build_stubbed(:alchemy_attachment) } - let(:essence) { build_stubbed(:alchemy_essence_audio, attachment: attachment) } - let(:content) { build_stubbed(:alchemy_content, essence: essence) } - - subject do - render partial: "alchemy/essences/essence_audio_editor", locals: { - essence_audio_editor: Alchemy::ContentEditor.new(content), - } - rendered - end - - before do - view.class.send :include, Alchemy::Admin::BaseHelper - allow(view).to receive(:content_label).and_return("") - end - - context "with ingredient present" do - before do - allow(content).to receive(:ingredient).and_return(attachment) - end - - it "renders a hidden field with attachment id" do - is_expected.to have_selector("input[type='hidden'][value='#{attachment.id}']") - end - - it "renders a link to open the attachment library overlay" do - within ".essence_audio_tools" do - is_expected.to have_selector("a[href='/admin/attachments?content_id=#{content.id}']") - end - end - - it "renders a link to edit the essence" do - within ".essence_audio_tools" do - is_expected.to have_selector("a[href='/admin/essence_audios/#{essence.id}/edit']") - end - end - - context "with content settings `only`" do - it "renders a link to open the attachment library overlay with only pdfs" do - within ".essence_audio_tools" do - expect(content).to receive(:settings).at_least(:once).and_return({ only: "pdf" }) - is_expected.to have_selector("a[href='/admin/attachments?content_id=#{content.id}&only=pdf']") - end - end - end - - context "with content settings `except`" do - it "renders a link to open the attachment library overlay without pdfs" do - within ".essence_audio_tools" do - expect(content).to receive(:settings).at_least(:once).and_return({ except: "pdf" }) - is_expected.to have_selector("a[href='/admin/attachments?content_id=#{content.id}&except=pdf']") - end - end - end - end - - context "without ingredient present" do - before do - allow(content).to receive(:ingredient).and_return(nil) - end - - it "renders a hidden field for attachment_id" do - is_expected.to have_selector("input[type='hidden'][name='contents[#{content.id}][attachment_id]']") - end - end -end diff --git a/spec/views/essences/essence_audio_view_spec.rb b/spec/views/essences/essence_audio_view_spec.rb deleted file mode 100644 index 40f639cfe0..0000000000 --- a/spec/views/essences/essence_audio_view_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_audio_view" do - let(:file) do - File.new(File.expand_path("../../fixtures/image with spaces.png", __dir__)) - end - - let(:attachment) do - build_stubbed(:alchemy_attachment, file: file, name: "a podcast", file_name: "image with spaces.png") - end - - let(:essence) { Alchemy::EssenceAudio.new(attachment: attachment) } - let(:content) { Alchemy::Content.new(essence: essence) } - - context "without attachment" do - let(:essence) { Alchemy::EssenceAudio.new(attachment: nil) } - - it "renders nothing" do - render content, content: content - expect(rendered).to eq("") - end - end - - context "with attachment" do - it "renders a audio tag with source" do - render content, content: content - expect(rendered).to have_selector( - "audio[controls] source[src]" - ) - end - end -end diff --git a/spec/views/essences/essence_boolean_editor_spec.rb b/spec/views/essences/essence_boolean_editor_spec.rb deleted file mode 100644 index 30df6d1b70..0000000000 --- a/spec/views/essences/essence_boolean_editor_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_boolean_editor" do - let(:element) { create(:alchemy_element, name: "all_you_can_eat") } - let(:content) { Alchemy::Content.create(name: "essence_boolean", type: "EssenceBoolean", element: element) } - - let(:content_definition) do - { - name: "essence_boolean", - type: "EssenceBoolean", - }.with_indifferent_access - end - - before do - expect(element).to receive(:content_definition_for) { content_definition } - allow_any_instance_of(Alchemy::Content).to receive(:definition) { content_definition } - allow(view).to receive(:render_content_name).and_return(content.name) - allow(view).to receive(:render_hint_for).and_return("") - end - - subject do - render partial: "alchemy/essences/essence_boolean_editor", locals: { - essence_boolean_editor: Alchemy::ContentEditor.new(content), - } - rendered - end - - it "renders a checkbox" do - is_expected.to have_selector('input[type="checkbox"]') - end - - context "with default value given in content settings" do - let(:content_definition) do - { - name: "essence_boolean", - type: "EssenceBoolean", - default: true, - }.with_indifferent_access - end - - it "checks the checkbox" do - is_expected.to have_selector('input[type="checkbox"][checked="checked"]') - end - end -end diff --git a/spec/views/essences/essence_boolean_view_spec.rb b/spec/views/essences/essence_boolean_view_spec.rb deleted file mode 100644 index 1f69be058a..0000000000 --- a/spec/views/essences/essence_boolean_view_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_boolean_view" do - context "with true as ingredient" do - let(:content) { Alchemy::EssenceBoolean.new(ingredient: true) } - before { allow(Alchemy).to receive(:t).and_return("true") } - - it "renders true" do - render content, content: content - expect(rendered).to have_content("true") - end - end - - context "with false as ingredient" do - let(:content) { Alchemy::EssenceBoolean.new(ingredient: false) } - before { allow(Alchemy).to receive(:t).and_return("false") } - - it "renders false" do - render content, content: content - expect(rendered).to have_content("false") - end - end -end diff --git a/spec/views/essences/essence_date_editor_spec.rb b/spec/views/essences/essence_date_editor_spec.rb deleted file mode 100644 index 57eb2c64ab..0000000000 --- a/spec/views/essences/essence_date_editor_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe "alchemy/essences/_essence_date_editor" do - let(:content) { Alchemy::Content.new(essence: essence) } - let(:essence) { Alchemy::EssenceDate.new } - - before do - view.class.send(:include, Alchemy::Admin::BaseHelper) - allow(view).to receive(:content_label).and_return(content.name) - end - - it "renders a datepicker" do - render "alchemy/essences/essence_date_editor", essence_date_editor: Alchemy::ContentEditor.new(content) - expect(rendered).to have_css('input[type="text"][data-datepicker-type="date"].date') - end -end diff --git a/spec/views/essences/essence_date_view_spec.rb b/spec/views/essences/essence_date_view_spec.rb deleted file mode 100644 index ecba8b136b..0000000000 --- a/spec/views/essences/essence_date_view_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_date_view" do - let(:essence) { Alchemy::EssenceDate.new(date: "2013-10-27 21:14:16 +0100".to_datetime) } - let(:content) { Alchemy::Content.new(essence: essence) } - let(:options) { {} } - - before do - allow(view).to receive(:options).and_return(options) - end - - context "with date value" do - context "without date_format passed" do - it "translates the date value with default format" do - render content, content: content - expect(rendered).to have_content("Sun, 27 Oct 2013 20:14:16 +0000") - end - end - - context "with option date_format set to rfc822" do - let(:options) { {date_format: "rfc822"} } - - it "renders the date rfc822 conform" do - render content, content: content - expect(rendered).to have_content("Sun, 27 Oct 2013 20:14:16 +0000") - end - end - end - - context "with blank date value" do - let(:essence) { Alchemy::EssenceDate.new(date: nil) } - - it "renders nothing" do - render content, content: content - expect(rendered).to eq("") - end - end -end diff --git a/spec/views/essences/essence_file_editor_spec.rb b/spec/views/essences/essence_file_editor_spec.rb deleted file mode 100644 index 1abe478281..0000000000 --- a/spec/views/essences/essence_file_editor_spec.rb +++ /dev/null @@ -1,71 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_file_editor" do - let(:attachment) { build_stubbed(:alchemy_attachment) } - let(:essence) { build_stubbed(:alchemy_essence_file, attachment: attachment) } - let(:content) { build_stubbed(:alchemy_content, essence: essence) } - - subject do - render partial: "alchemy/essences/essence_file_editor", locals: { - essence_file_editor: Alchemy::ContentEditor.new(content), - } - rendered - end - - before do - view.class.send :include, Alchemy::Admin::BaseHelper - allow(view).to receive(:content_label).and_return("") - end - - context "with ingredient present" do - before do - allow(content).to receive(:ingredient).and_return(attachment) - end - - it "renders a hidden field with attachment id" do - is_expected.to have_selector("input[type='hidden'][value='#{attachment.id}']") - end - - it "renders a link to open the attachment library overlay" do - within ".essence_file_tools" do - is_expected.to have_selector("a[href='/admin/attachments?content_id=#{content.id}']") - end - end - - it "renders a link to edit the essence" do - within ".essence_file_tools" do - is_expected.to have_selector("a[href='/admin/essence_files/#{essence.id}/edit']") - end - end - - context "with content settings `only`" do - it "renders a link to open the attachment library overlay with only pdfs" do - within ".essence_file_tools" do - expect(content).to receive(:settings).at_least(:once).and_return({only: "pdf"}) - is_expected.to have_selector("a[href='/admin/attachments?content_id=#{content.id}&only=pdf']") - end - end - end - - context "with content settings `except`" do - it "renders a link to open the attachment library overlay without pdfs" do - within ".essence_file_tools" do - expect(content).to receive(:settings).at_least(:once).and_return({except: "pdf"}) - is_expected.to have_selector("a[href='/admin/attachments?content_id=#{content.id}&except=pdf']") - end - end - end - end - - context "without ingredient present" do - before do - allow(content).to receive(:ingredient).and_return(nil) - end - - it "renders a hidden field for attachment_id" do - is_expected.to have_selector("input[type='hidden'][name='contents[#{content.id}][attachment_id]']") - end - end -end diff --git a/spec/views/essences/essence_file_view_spec.rb b/spec/views/essences/essence_file_view_spec.rb deleted file mode 100644 index e4036845d0..0000000000 --- a/spec/views/essences/essence_file_view_spec.rb +++ /dev/null @@ -1,88 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_file_view" do - let(:file) do - File.new(File.expand_path("../../fixtures/image with spaces.png", __dir__)) - end - - let(:attachment) do - build_stubbed(:alchemy_attachment, file: file, name: "an image", file_name: "image with spaces.png") - end - - let(:essence) { Alchemy::EssenceFile.new(attachment: attachment) } - let(:content) { Alchemy::Content.new(essence: essence) } - - context "without attachment" do - let(:essence) { Alchemy::EssenceFile.new(attachment: nil) } - - it "renders nothing" do - render content, content: content - expect(rendered).to eq("") - end - end - - context "with attachment" do - it "renders a link to download the attachment" do - render content, content: content - expect(rendered).to have_selector( - "a[href='/attachment/#{attachment.id}/download/#{attachment.slug}.#{attachment.suffix}']" - ) - end - - context "with no link_text set" do - it "has this attachments name as link text" do - render content, content: content - expect(rendered).to have_selector("a:contains('#{attachment.name}')") - end - end - - context "with link_text set in the local options" do - it "has this value as link text" do - render content, content: content, options: { link_text: "Download this file" } - expect(rendered).to have_selector("a:contains('Download this file')") - end - end - - context "with link_text set in the content settings" do - before do - allow(content).to receive(:settings) { { link_text: "Download this file" } } - end - - it "has this value as link text" do - render content, content: content - expect(rendered).to have_selector("a:contains('Download this file')") - end - end - - context "with link_text stored in the essence attribute" do - before do - allow(essence).to receive(:link_text) { "Download this file" } - end - - it "has this value as link text" do - render content, content: content - expect(rendered).to have_selector("a:contains('Download this file')") - end - end - - context "with html_options given" do - it "renders the linked ingredient with these options" do - render content, content: content, html_options: { title: "Bar", class: "blue" } - expect(rendered).to have_selector('a.blue[title="Bar"]') - end - end - end - - context "with css_class set" do - before do - allow(essence).to receive(:css_class) { "file-download" } - end - - it "has this class at the link" do - render content, content: content - expect(rendered).to have_selector("a.file-download") - end - end -end diff --git a/spec/views/essences/essence_html_view_spec.rb b/spec/views/essences/essence_html_view_spec.rb deleted file mode 100644 index 3499809074..0000000000 --- a/spec/views/essences/essence_html_view_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_html_view" do - let(:essence) { Alchemy::EssenceHtml.new(source: '') } - let(:content) { Alchemy::Content.new(essence: essence) } - - context "without value" do - let(:essence) { Alchemy::EssenceHtml.new(source: nil) } - - it "renders nothing" do - render content, content: content - expect(rendered).to eq("") - end - end - - context "with value" do - it "renders the raw html source" do - render content, content: content - expect(rendered).to have_selector("script") - end - end -end diff --git a/spec/views/essences/essence_link_editor_spec.rb b/spec/views/essences/essence_link_editor_spec.rb deleted file mode 100644 index c01d97e5a0..0000000000 --- a/spec/views/essences/essence_link_editor_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_link_editor" do - let(:essence) { Alchemy::EssenceLink.new(link: "http://alchemy-cms.com") } - let(:content) { Alchemy::Content.new(essence: essence) } - let(:settings) { {} } - - before do - view.class.send :include, Alchemy::Admin::BaseHelper - allow(view).to receive(:content_label).and_return("1e Zahl") - render partial: "alchemy/essences/essence_link_editor", locals: { - essence_link_editor: Alchemy::ContentEditor.new(content), - } - end - - it "renders a disabled text input field" do - expect(rendered).to have_selector('input[type="text"][disabled]') - end - - it "renders link buttons" do - expect(rendered).to have_selector('input[type="hidden"][name="contents[][link]"]') - expect(rendered).to have_selector('input[type="hidden"][name="contents[][link_title]"]') - expect(rendered).to have_selector('input[type="hidden"][name="contents[][link_class_name]"]') - expect(rendered).to have_selector('input[type="hidden"][name="contents[][link_target]"]') - end -end diff --git a/spec/views/essences/essence_link_view_spec.rb b/spec/views/essences/essence_link_view_spec.rb deleted file mode 100644 index 94fca8cfff..0000000000 --- a/spec/views/essences/essence_link_view_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_link_view" do - let(:essence) { Alchemy::EssenceLink.new(link: "http://google.com") } - let(:content) { Alchemy::Content.new(essence: essence) } - let(:options) { {} } - - context "without value" do - let(:essence) { Alchemy::EssenceLink.new(link: nil) } - - it "renders nothing" do - render content, content: content, options: options, html_options: {} - expect(rendered).to eq("") - end - end - - it "renders a link" do - render content, content: content, options: options, html_options: {} - expect(rendered).to eq('http://google.com') - end - - context "with text option" do - let(:options) { {text: "Google"} } - - it "renders a link" do - render content, content: content, options: options, html_options: {} - expect(rendered).to eq('Google') - end - end - - context "with text setting on content definition" do - before do - allow(content).to receive(:settings).and_return({text: "Yahoo"}) - end - - it "renders a link" do - render content.essence, content: content, options: options, html_options: {} - expect(rendered).to eq('Yahoo') - end - end -end diff --git a/spec/views/essences/essence_page_editor_spec.rb b/spec/views/essences/essence_page_editor_spec.rb deleted file mode 100644 index 5b992c5426..0000000000 --- a/spec/views/essences/essence_page_editor_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe "alchemy/essences/_essence_page_editor" do - let(:content) { Alchemy::Content.new(essence: essence) } - let(:essence) { Alchemy::EssencePage.new } - - before do - view.class.send(:include, Alchemy::Admin::EssencesHelper) - allow(view).to receive(:content_label).and_return(content.name) - end - - subject do - render "alchemy/essences/essence_page_editor", essence_page_editor: Alchemy::ContentEditor.new(content) - rendered - end - - it "renders a page input" do - is_expected.to have_css("input.alchemy_selectbox.full_width") - end - - context "with a page related to essence" do - let(:page) { Alchemy::Page.new(id: 1) } - let(:essence) { Alchemy::EssencePage.new(page_id: page.id) } - - it "sets page id as value" do - is_expected.to have_css('input.alchemy_selectbox[value="1"]') - end - end -end diff --git a/spec/views/essences/essence_page_view_spec.rb b/spec/views/essences/essence_page_view_spec.rb deleted file mode 100644 index bc8ddb98a3..0000000000 --- a/spec/views/essences/essence_page_view_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_page_view" do - let(:page) { build(:alchemy_page, urlname: "a-page") } - let(:essence) { Alchemy::EssencePage.new(page: page) } - let(:content) { Alchemy::Content.new(essence: essence) } - - context "without page" do - let(:essence) { Alchemy::EssencePage.new } - - it "renders nothing" do - render content, content: content - expect(rendered).to eq("") - end - end - - context "with page" do - it "renders a link to the page" do - render content, content: content - expect(rendered).to have_selector("a[href='/#{page.urlname}']") - end - - it "has the page name as link text" do - render content, content: content - expect(rendered).to have_selector("a:contains('#{page.name}')") - end - end -end diff --git a/spec/views/essences/essence_picture_editor_spec.rb b/spec/views/essences/essence_picture_editor_spec.rb deleted file mode 100644 index f9575f0c54..0000000000 --- a/spec/views/essences/essence_picture_editor_spec.rb +++ /dev/null @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_picture_editor" do - let(:picture) { stub_model(Alchemy::Picture) } - - let(:essence_picture) do - stub_model( - Alchemy::EssencePicture, - picture: picture, - caption: "This is a cute cat", - ) - end - - let(:content) do - stub_model( - Alchemy::Content, - name: "image", - essence_type: "EssencePicture", - essence: essence_picture, - ) - end - - let(:settings) { Hash.new } - - before do - view.class.send(:include, Alchemy::Admin::BaseHelper) - view.class.send(:include, Alchemy::Admin::EssencesHelper) - allow(view).to receive(:content_label).and_return("") - allow(view).to receive(:essence_picture_thumbnail).and_return("") - end - - subject do - allow(content).to receive(:settings) { settings } - render partial: "alchemy/essences/essence_picture_editor", - locals: {essence_picture_editor: Alchemy::ContentEditor.new(content)} - rendered - end - - context "with settings[:deletable] being nil" do - it "should not render a button to link and unlink the picture" do - is_expected.to have_selector("a .icon.fa-link") - is_expected.to have_selector("a .icon.fa-unlink") - end - end - - context "with settings[:deletable] being false" do - let(:settings) do - { - linkable: false, - } - end - - it "should not render a button to link and unlink the picture" do - is_expected.to_not have_selector("a .icon.fa-link") - is_expected.to_not have_selector("a .icon.fa-unlink") - end - - it "but renders the disabled link and unlink icons" do - is_expected.to have_selector(".icon.fa-link") - is_expected.to have_selector(".icon.fa-unlink") - end - end - - context "with allow_image_cropping? true" do - before do - allow(essence_picture).to receive(:allow_image_cropping?) { true } - end - - it "shows cropping link" do - is_expected.to have_selector('a[href*="crop"]') - end - end - - context "with allow_image_cropping? false" do - before do - allow(essence_picture).to receive(:allow_image_cropping?) { false } - end - - it "shows disabled cropping link" do - is_expected.to have_selector("a.disabled .icon.fa-crop") - end - end -end diff --git a/spec/views/essences/essence_picture_view_spec.rb b/spec/views/essences/essence_picture_view_spec.rb deleted file mode 100644 index 8bc418c286..0000000000 --- a/spec/views/essences/essence_picture_view_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_picture_view" do - let(:picture) { build_stubbed(:alchemy_picture) } - let(:essence) { build_stubbed(:alchemy_essence_picture, picture: picture) } - let(:content) { build_stubbed(:alchemy_content, essence: essence) } - - it "renders when passing only the content" do - render content, content: content - expect(rendered).to have_selector("img") - end -end diff --git a/spec/views/essences/essence_richtext_view_spec.rb b/spec/views/essences/essence_richtext_view_spec.rb deleted file mode 100644 index d838c52005..0000000000 --- a/spec/views/essences/essence_richtext_view_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_richtext_view" do - let(:essence) { Alchemy::EssenceRichtext.new(body: "

Lorem ipsum dolor sit amet

consectetur adipiscing elit.

", stripped_body: "Lorem ipsum dolor sit amet consectetur adipiscing elit.") } - let(:content) { Alchemy::Content.new(essence: essence) } - - it "renders the html body" do - render content, content: content - expect(rendered).to have_content("Lorem ipsum dolor sit amet consectetur adipiscing elit.") - expect(rendered).to have_selector("h1") - end - - context "with options[:plain_text] true" do - it "renders the text body" do - render content, content: content, options: {plain_text: true} - expect(rendered).to have_content("Lorem ipsum dolor sit amet consectetur adipiscing elit.") - expect(rendered).to_not have_selector("h1") - end - end - - context "with content.settings[:plain_text] true" do - before do - allow(content).to receive(:settings).and_return({plain_text: true}) - end - - it "renders the text body" do - render content.essence, content: content - expect(rendered).to have_content("Lorem ipsum dolor sit amet consectetur adipiscing elit.") - expect(rendered).to_not have_selector("h1") - end - end -end diff --git a/spec/views/essences/essence_select_editor_spec.rb b/spec/views/essences/essence_select_editor_spec.rb deleted file mode 100644 index f6f83f65af..0000000000 --- a/spec/views/essences/essence_select_editor_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe "alchemy/essences/_essence_select_editor" do - let(:content) { Alchemy::Content.new(essence: essence) } - let(:essence) { Alchemy::EssenceSelect.new } - - before do - view.class.send(:include, Alchemy::Admin::BaseHelper) - allow(view).to receive(:content_label).and_return(content.name) - end - - subject do - render "alchemy/essences/essence_select_editor", essence_select_editor: Alchemy::ContentEditor.new(content) - rendered - end - - context "if no select values are set" do - it "renders a warning" do - is_expected.to have_css(".warning") - end - end - - context "if select values are set" do - before do - expect(content).to receive(:settings).at_least(:once) do - { - select_values: %w(red blue yellow), - } - end - end - - it "renders a select box" do - is_expected.to have_css("select.alchemy_selectbox") - end - end -end diff --git a/spec/views/essences/essence_select_view_spec.rb b/spec/views/essences/essence_select_view_spec.rb deleted file mode 100644 index 5e260f7bc7..0000000000 --- a/spec/views/essences/essence_select_view_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_select_view" do - let(:content) { Alchemy::Content.new(essence: essence) } - let(:essence) { Alchemy::EssenceSelect.new(ingredient: "blue") } - - it "renders the ingredient" do - render content, content: content - expect(rendered).to have_content("blue") - end -end diff --git a/spec/views/essences/essence_text_editor_spec.rb b/spec/views/essences/essence_text_editor_spec.rb deleted file mode 100644 index f976929760..0000000000 --- a/spec/views/essences/essence_text_editor_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_text_editor" do - let(:essence) { Alchemy::EssenceText.new(body: "1234") } - let(:content) { Alchemy::Content.new(essence: essence) } - let(:settings) { {} } - - before do - view.class.send :include, Alchemy::Admin::BaseHelper - allow(view).to receive(:content_label).and_return("1e Zahl") - allow(content).to receive(:settings) { settings } - render partial: "alchemy/essences/essence_text_editor", locals: { - essence_text_editor: Alchemy::ContentEditor.new(content), - } - end - - context "with no input type set" do - it "renders an input field of type number" do - expect(rendered).to have_selector('input[type="text"]') - end - end - - context "with a different input type set" do - let(:settings) do - { - input_type: "number", - } - end - - it "renders an input field of type number" do - expect(rendered).to have_selector('input[type="number"]') - end - end - - context "with settings linkable set to true" do - let(:settings) do - { - linkable: true, - } - end - - it "renders link buttons" do - expect(rendered).to have_selector('input[type="hidden"][name="contents[][link]"]') - expect(rendered).to have_selector('input[type="hidden"][name="contents[][link_title]"]') - expect(rendered).to have_selector('input[type="hidden"][name="contents[][link_class_name]"]') - expect(rendered).to have_selector('input[type="hidden"][name="contents[][link_target]"]') - end - end -end diff --git a/spec/views/essences/essence_text_view_spec.rb b/spec/views/essences/essence_text_view_spec.rb deleted file mode 100644 index b3df308bbd..0000000000 --- a/spec/views/essences/essence_text_view_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_text_view" do - let(:essence) { Alchemy::EssenceText.new(body: "Hello World") } - let(:content) { Alchemy::Content.new(essence: essence) } - - context "with blank link value" do - it "only renders the ingredient" do - render content, content: content - expect(rendered).to have_content("Hello World") - expect(rendered).to_not have_selector("a") - end - end - - context "with a link set" do - let(:essence) { Alchemy::EssenceText.new(body: "Hello World", link: "http://google.com", link_title: "Foo", link_target: "blank") } - - it "renders the linked ingredient" do - render content, content: content - expect(rendered).to have_content("Hello World") - expect(rendered).to have_selector('a[title="Foo"][target="_blank"][data-link-target="blank"][href="http://google.com"]') - end - - context "with html_options given" do - it "renders the linked with these options" do - render content, content: content, html_options: {title: "Bar", class: "blue"} - expect(rendered).to have_selector('a.blue[title="Bar"][target="_blank"][data-link-target="blank"]') - end - end - - context "but with options disable_link set to true" do - it "only renders the ingredient" do - render content, content: content, options: {disable_link: true} - expect(rendered).to have_content("Hello World") - expect(rendered).to_not have_selector("a") - end - end - - context "but with content settings disable_link set to true" do - before do - allow(content).to receive(:settings).and_return({disable_link: true}) - end - - it "only renders the ingredient" do - render content.essence, content: content - expect(rendered).to have_content("Hello World") - expect(rendered).to_not have_selector("a") - end - end - end -end diff --git a/spec/views/essences/essence_video_editor_spec.rb b/spec/views/essences/essence_video_editor_spec.rb deleted file mode 100644 index a263720826..0000000000 --- a/spec/views/essences/essence_video_editor_spec.rb +++ /dev/null @@ -1,71 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_video_editor" do - let(:attachment) { build_stubbed(:alchemy_attachment) } - let(:essence) { build_stubbed(:alchemy_essence_video, attachment: attachment) } - let(:content) { build_stubbed(:alchemy_content, essence: essence) } - - subject do - render partial: "alchemy/essences/essence_video_editor", locals: { - essence_video_editor: Alchemy::ContentEditor.new(content), - } - rendered - end - - before do - view.class.send :include, Alchemy::Admin::BaseHelper - allow(view).to receive(:content_label).and_return("") - end - - context "with ingredient present" do - before do - allow(content).to receive(:ingredient).and_return(attachment) - end - - it "renders a hidden field with attachment id" do - is_expected.to have_selector("input[type='hidden'][value='#{attachment.id}']") - end - - it "renders a link to open the attachment library overlay" do - within ".essence_video_tools" do - is_expected.to have_selector("a[href='/admin/attachments?content_id=#{content.id}']") - end - end - - it "renders a link to edit the essence" do - within ".essence_video_tools" do - is_expected.to have_selector("a[href='/admin/essence_videos/#{essence.id}/edit']") - end - end - - context "with content settings `only`" do - it "renders a link to open the attachment library overlay with only pdfs" do - within ".essence_video_tools" do - expect(content).to receive(:settings).at_least(:once).and_return({ only: "pdf" }) - is_expected.to have_selector("a[href='/admin/attachments?content_id=#{content.id}&only=pdf']") - end - end - end - - context "with content settings `except`" do - it "renders a link to open the attachment library overlay without pdfs" do - within ".essence_video_tools" do - expect(content).to receive(:settings).at_least(:once).and_return({ except: "pdf" }) - is_expected.to have_selector("a[href='/admin/attachments?content_id=#{content.id}&except=pdf']") - end - end - end - end - - context "without ingredient present" do - before do - allow(content).to receive(:ingredient).and_return(nil) - end - - it "renders a hidden field for attachment_id" do - is_expected.to have_selector("input[type='hidden'][name='contents[#{content.id}][attachment_id]']") - end - end -end diff --git a/spec/views/essences/essence_video_view_spec.rb b/spec/views/essences/essence_video_view_spec.rb deleted file mode 100644 index b83f125592..0000000000 --- a/spec/views/essences/essence_video_view_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "alchemy/essences/_essence_video_view" do - let(:file) do - File.new(File.expand_path("../../fixtures/image with spaces.png", __dir__)) - end - - let(:attachment) do - build_stubbed(:alchemy_attachment, file: file, name: "a movie", file_name: "image with spaces.png") - end - - let(:essence) { Alchemy::EssenceVideo.new(attachment: attachment) } - let(:content) { Alchemy::Content.new(essence: essence) } - - context "without attachment" do - let(:essence) { Alchemy::EssenceVideo.new(attachment: nil) } - - it "renders nothing" do - render content, content: content - expect(rendered).to eq("") - end - end - - context "with attachment" do - it "renders a video tag with source" do - render content, content: content - expect(rendered).to have_selector( - "video[controls] source[src]" - ) - end - end -end