alchemy_cms 3.3.0.rc1 → 3.3.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -2
- data/Gemfile +1 -0
- data/alchemy_cms.gemspec +6 -6
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +0 -7
- data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +4 -4
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +51 -5
- data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +0 -2
- data/app/assets/stylesheets/alchemy/elements.scss +2 -2
- data/app/controllers/alchemy/admin/elements_controller.rb +2 -0
- data/app/controllers/alchemy/admin/pages_controller.rb +11 -3
- data/app/controllers/alchemy/admin/pictures_controller.rb +1 -0
- data/app/models/alchemy/element.rb +3 -1
- data/app/models/alchemy/element/element_contents.rb +2 -7
- data/app/models/alchemy/element/presenters.rb +11 -4
- data/app/models/alchemy/page.rb +3 -1
- data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +0 -1
- data/app/views/alchemy/admin/contents/create.js.erb +0 -1
- data/app/views/alchemy/admin/elements/_element_header.html.erb +3 -1
- data/app/views/alchemy/admin/elements/order.js.erb +25 -10
- data/app/views/alchemy/admin/elements/update.js.erb +1 -2
- data/app/views/alchemy/admin/essence_files/assign.js.erb +0 -1
- data/app/views/alchemy/admin/essence_pictures/assign.js.erb +0 -1
- data/app/views/alchemy/admin/legacy_page_urls/create.js.erb +0 -1
- data/app/views/alchemy/admin/pages/destroy.js.erb +0 -1
- data/app/views/alchemy/admin/pages/update.js.erb +6 -4
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +2 -1
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -7
- data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +0 -1
- data/bin/alchemy +1 -1
- data/bin/rspec +3 -2
- data/bin/spring +6 -6
- data/config/alchemy/config.yml +6 -1
- data/lib/alchemy/seeder.rb +9 -3
- data/lib/alchemy/version.rb +1 -1
- metadata +6 -471
- data/spec/controllers/alchemy/admin/attachments_controller_spec.rb +0 -193
- data/spec/controllers/alchemy/admin/base_controller_spec.rb +0 -87
- data/spec/controllers/alchemy/admin/clipboard_controller_spec.rb +0 -60
- data/spec/controllers/alchemy/admin/contents_controller_spec.rb +0 -78
- data/spec/controllers/alchemy/admin/dashboard_controller_spec.rb +0 -144
- data/spec/controllers/alchemy/admin/elements_controller_spec.rb +0 -496
- data/spec/controllers/alchemy/admin/essence_files_controller_spec.rb +0 -76
- data/spec/controllers/alchemy/admin/essence_pictures_controller_spec.rb +0 -202
- data/spec/controllers/alchemy/admin/languages_controller_spec.rb +0 -73
- data/spec/controllers/alchemy/admin/layoutpages_controller_spec.rb +0 -21
- data/spec/controllers/alchemy/admin/pages_controller_spec.rb +0 -639
- data/spec/controllers/alchemy/admin/pictures_controller_spec.rb +0 -383
- data/spec/controllers/alchemy/admin/resources_controller_spec.rb +0 -81
- data/spec/controllers/alchemy/admin/tags_controller_spec.rb +0 -63
- data/spec/controllers/alchemy/admin/trash_controller_spec.rb +0 -67
- data/spec/controllers/alchemy/api/contents_controller_spec.rb +0 -125
- data/spec/controllers/alchemy/api/elements_controller_spec.rb +0 -124
- data/spec/controllers/alchemy/api/pages_controller_spec.rb +0 -167
- data/spec/controllers/alchemy/attachments_controller_spec.rb +0 -64
- data/spec/controllers/alchemy/base_controller_spec.rb +0 -106
- data/spec/controllers/alchemy/elements_controller_spec.rb +0 -48
- data/spec/controllers/alchemy/messages_controller_spec.rb +0 -204
- data/spec/controllers/alchemy/on_page_layout_mixin_spec.rb +0 -330
- data/spec/controllers/alchemy/pages_controller_spec.rb +0 -343
- data/spec/controllers/alchemy/pictures_controller_spec.rb +0 -415
- data/spec/dummy/Rakefile +0 -6
- data/spec/dummy/app/assets/javascripts/application.js +0 -13
- data/spec/dummy/app/assets/stylesheets/application.css +0 -15
- data/spec/dummy/app/controllers/admin/events_controller.rb +0 -3
- data/spec/dummy/app/controllers/application_controller.rb +0 -15
- data/spec/dummy/app/controllers/login_controller.rb +0 -5
- data/spec/dummy/app/helpers/application_helper.rb +0 -2
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/ability.rb +0 -9
- data/spec/dummy/app/models/dummy_model.rb +0 -3
- data/spec/dummy/app/models/dummy_user.rb +0 -15
- data/spec/dummy/app/models/event.rb +0 -10
- data/spec/dummy/app/models/location.rb +0 -3
- data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_editor.html.erb +0 -11
- data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_view.html.erb +0 -31
- data/spec/dummy/app/views/alchemy/elements/_article_editor.html.erb +0 -6
- data/spec/dummy/app/views/alchemy/elements/_article_view.html.erb +0 -10
- data/spec/dummy/app/views/alchemy/elements/_bild_editor.html.erb +0 -3
- data/spec/dummy/app/views/alchemy/elements/_bild_view.html.erb +0 -5
- data/spec/dummy/app/views/alchemy/elements/_contactform_editor.html.erb +0 -6
- data/spec/dummy/app/views/alchemy/elements/_contactform_view.html.erb +0 -16
- data/spec/dummy/app/views/alchemy/elements/_download_editor.html.erb +0 -3
- data/spec/dummy/app/views/alchemy/elements/_download_view.html.erb +0 -5
- data/spec/dummy/app/views/alchemy/elements/_erb_element_editor.html.erb +0 -3
- data/spec/dummy/app/views/alchemy/elements/_erb_element_view.html.erb +0 -5
- data/spec/dummy/app/views/alchemy/elements/_header_editor.html.erb +0 -3
- data/spec/dummy/app/views/alchemy/elements/_header_view.html.erb +0 -5
- data/spec/dummy/app/views/alchemy/elements/_headline_editor.html.erb +0 -1
- data/spec/dummy/app/views/alchemy/elements/_headline_view.html.erb +0 -1
- data/spec/dummy/app/views/alchemy/elements/_news_editor.html.erb +0 -5
- data/spec/dummy/app/views/alchemy/elements/_news_view.html.erb +0 -11
- data/spec/dummy/app/views/alchemy/elements/_search_editor.html.erb +0 -1
- data/spec/dummy/app/views/alchemy/elements/_search_view.html.erb +0 -4
- data/spec/dummy/app/views/alchemy/elements/_slide_editor.html.erb +0 -3
- data/spec/dummy/app/views/alchemy/elements/_slide_view.html.erb +0 -5
- data/spec/dummy/app/views/alchemy/elements/_slider_editor.html.erb +0 -2
- data/spec/dummy/app/views/alchemy/elements/_slider_view.html.erb +0 -4
- data/spec/dummy/app/views/alchemy/elements/_text_editor.html.erb +0 -3
- data/spec/dummy/app/views/alchemy/elements/_text_view.html.erb +0 -5
- data/spec/dummy/app/views/alchemy/page_layouts/_standard.html.erb +0 -15
- data/spec/dummy/app/views/layouts/application.html.erb +0 -17
- data/spec/dummy/bin/bundle +0 -3
- data/spec/dummy/bin/rails +0 -4
- data/spec/dummy/bin/rake +0 -4
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/config/alchemy/cells.yml +0 -5
- data/spec/dummy/config/alchemy/elements.yml +0 -109
- data/spec/dummy/config/alchemy/page_layouts.yml +0 -32
- data/spec/dummy/config/application.rb +0 -32
- data/spec/dummy/config/boot.rb +0 -5
- data/spec/dummy/config/database.yml +0 -32
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -41
- data/spec/dummy/config/environments/production.rb +0 -77
- data/spec/dummy/config/environments/test.rb +0 -43
- data/spec/dummy/config/initializers/alchemy.rb +0 -3
- data/spec/dummy/config/initializers/assets.rb +0 -11
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/cookies_serializer.rb +0 -3
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/spec/dummy/config/initializers/inflections.rb +0 -16
- data/spec/dummy/config/initializers/mime_types.rb +0 -4
- data/spec/dummy/config/initializers/secret_token.rb +0 -12
- data/spec/dummy/config/initializers/session_store.rb +0 -3
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/kl.yml +0 -2
- data/spec/dummy/config/routes.rb +0 -12
- data/spec/dummy/config/secrets.yml +0 -22
- data/spec/dummy/db/migrate/20121026104128_create_events.rb +0 -20
- data/spec/dummy/db/migrate/20130328101418_create_locations.rb +0 -9
- data/spec/dummy/db/migrate/20130827094554_alchemy_two_point_six.rb +0 -1
- data/spec/dummy/db/migrate/20130828121054_remove_do_not_index_from_alchemy_essence_texts.rb +0 -1
- data/spec/dummy/db/migrate/20130828121120_remove_do_not_index_from_alchemy_essence_richtexts.rb +0 -1
- data/spec/dummy/db/migrate/20130918201742_add_published_at_to_alchemy_pages.rb +0 -1
- data/spec/dummy/db/migrate/20131209225243_create_dummy_users.rb +0 -9
- data/spec/dummy/db/migrate/20150122213511_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb +0 -31
- data/spec/dummy/db/migrate/20150122213512_add_missing_unique_indices.acts_as_taggable_on_engine.rb +0 -20
- data/spec/dummy/db/migrate/20150122213513_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb +0 -15
- data/spec/dummy/db/migrate/20150122213514_add_missing_taggable_index.acts_as_taggable_on_engine.rb +0 -10
- data/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb +0 -7
- data/spec/dummy/db/migrate/20150608204610_add_parent_element_id_to_alchemy_elements.rb +0 -1
- data/spec/dummy/db/migrate/20150729151825_add_link_text_to_alchemy_essence_files.rb +0 -1
- data/spec/dummy/db/migrate/20150906195818_add_locale_to_alchemy_languages.rb +0 -1
- data/spec/dummy/db/schema.rb +0 -326
- data/spec/dummy/db/seeds.rb +0 -1
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/public/404.html +0 -67
- data/spec/dummy/public/422.html +0 -67
- data/spec/dummy/public/500.html +0 -66
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/spec/javascripts +0 -1
- data/spec/factories.rb +0 -13
- data/spec/features/admin/admin_layout_spec.rb +0 -14
- data/spec/features/admin/dashboard_spec.rb +0 -81
- data/spec/features/admin/edit_elements_feature_spec.rb +0 -36
- data/spec/features/admin/language_tree_feature_spec.rb +0 -32
- data/spec/features/admin/languages_features_spec.rb +0 -65
- data/spec/features/admin/legacy_page_url_management_spec.rb +0 -62
- data/spec/features/admin/link_overlay_spec.rb +0 -53
- data/spec/features/admin/locale_select_feature_spec.rb +0 -25
- data/spec/features/admin/modules_integration_spec.rb +0 -23
- data/spec/features/admin/navigation_feature_spec.rb +0 -22
- data/spec/features/admin/page_creation_feature_spec.rb +0 -51
- data/spec/features/admin/page_editing_feature_spec.rb +0 -135
- data/spec/features/admin/picture_library_integration_spec.rb +0 -62
- data/spec/features/admin/resources_integration_spec.rb +0 -128
- data/spec/features/admin/site_select_feature_spec.rb +0 -31
- data/spec/features/admin/tinymce_feature_spec.rb +0 -33
- data/spec/features/navigation_spec.rb +0 -9
- data/spec/features/page_feature_spec.rb +0 -186
- data/spec/features/page_redirects_spec.rb +0 -358
- data/spec/features/picture_security_spec.rb +0 -29
- data/spec/features/security_spec.rb +0 -24
- data/spec/features/translation_integration_spec.rb +0 -51
- data/spec/fixtures/500x500.png +0 -0
- data/spec/fixtures/80x60.png +0 -0
- data/spec/fixtures/animated.gif +0 -0
- data/spec/fixtures/image with spaces.png +0 -0
- data/spec/fixtures/image.png +0 -0
- data/spec/fixtures/image2.PNG +0 -0
- data/spec/fixtures/image3.jpeg +0 -0
- data/spec/helpers/alchemy/admin/attachments_helper_spec.rb +0 -15
- data/spec/helpers/alchemy/admin/base_helper_spec.rb +0 -280
- data/spec/helpers/alchemy/admin/contents_helper_spec.rb +0 -46
- data/spec/helpers/alchemy/admin/elements_helper_spec.rb +0 -314
- data/spec/helpers/alchemy/admin/essences_helper_spec.rb +0 -201
- data/spec/helpers/alchemy/admin/navigation_helper_spec.rb +0 -294
- data/spec/helpers/alchemy/admin/pages_helper_spec.rb +0 -63
- data/spec/helpers/alchemy/admin/pictures_helper_spec.rb +0 -28
- data/spec/helpers/alchemy/admin/tags_helper_spec.rb +0 -111
- data/spec/helpers/alchemy/base_helper_spec.rb +0 -44
- data/spec/helpers/alchemy/elements_block_helper_spec.rb +0 -135
- data/spec/helpers/alchemy/elements_helper_spec.rb +0 -326
- data/spec/helpers/alchemy/essences_helper_spec.rb +0 -85
- data/spec/helpers/alchemy/pages_helper_spec.rb +0 -499
- data/spec/helpers/alchemy/picture_url_helpers_spec.rb +0 -78
- data/spec/helpers/alchemy/url_helper_spec.rb +0 -200
- data/spec/javascripts/alchemy/dialog_spec.coffee +0 -82
- data/spec/javascripts/alchemy/link_overlay_spec.coffee +0 -25
- data/spec/javascripts/alchemy_integration_spec.coffee +0 -3
- data/spec/javascripts/fixtures/select.html +0 -3
- data/spec/javascripts/helpers/mock-ajax.js +0 -199
- data/spec/javascripts/helpers/test_responses/test_responses.js +0 -1
- data/spec/javascripts/support/jasmine.yml +0 -29
- data/spec/libraries/auth_accessors_spec.rb +0 -40
- data/spec/libraries/config_spec.rb +0 -111
- data/spec/libraries/controller_actions_spec.rb +0 -133
- data/spec/libraries/i18n_spec.rb +0 -37
- data/spec/libraries/kaminari/scoped_pagination_url_helper_spec.rb +0 -30
- data/spec/libraries/modules_spec.rb +0 -67
- data/spec/libraries/mount_point_spec.rb +0 -77
- data/spec/libraries/page_layout_spec.rb +0 -150
- data/spec/libraries/paths_spec.rb +0 -15
- data/spec/libraries/permissions_spec.rb +0 -260
- data/spec/libraries/resource_spec.rb +0 -344
- data/spec/libraries/resources_helper_spec.rb +0 -193
- data/spec/libraries/shell_spec.rb +0 -121
- data/spec/libraries/template_tracker_spec.rb +0 -85
- data/spec/libraries/tinymce_spec.rb +0 -111
- data/spec/libraries/userstamp_spec.rb +0 -10
- data/spec/mailers/alchemy/messages_spec.rb +0 -21
- data/spec/models/alchemy/attachment_spec.rb +0 -250
- data/spec/models/alchemy/cell_spec.rb +0 -101
- data/spec/models/alchemy/content_spec.rb +0 -513
- data/spec/models/alchemy/element_spec.rb +0 -862
- data/spec/models/alchemy/element_to_page_spec.rb +0 -13
- data/spec/models/alchemy/essence_boolean_spec.rb +0 -10
- data/spec/models/alchemy/essence_date_spec.rb +0 -28
- data/spec/models/alchemy/essence_file_spec.rb +0 -40
- data/spec/models/alchemy/essence_html_spec.rb +0 -18
- data/spec/models/alchemy/essence_link_spec.rb +0 -10
- data/spec/models/alchemy/essence_picture_spec.rb +0 -255
- data/spec/models/alchemy/essence_richtext_spec.rb +0 -23
- data/spec/models/alchemy/essence_select_spec.rb +0 -10
- data/spec/models/alchemy/essence_text_spec.rb +0 -110
- data/spec/models/alchemy/language_spec.rb +0 -243
- data/spec/models/alchemy/legacy_page_url_spec.rb +0 -21
- data/spec/models/alchemy/message_spec.rb +0 -55
- data/spec/models/alchemy/page_spec.rb +0 -2108
- data/spec/models/alchemy/picture_spec.rb +0 -418
- data/spec/models/alchemy/site_spec.rb +0 -168
- data/spec/models/alchemy/tag_spec.rb +0 -29
- data/spec/models/dummy_model_spec.rb +0 -10
- data/spec/requests/alchemy/admin/resources_requests_spec.rb +0 -26
- data/spec/requests/alchemy/admin/site_requests_spec.rb +0 -19
- data/spec/requests/alchemy/site_requests_spec.rb +0 -18
- data/spec/requests/alchemy/sitemap_spec.rb +0 -56
- data/spec/routing/api_routing_spec.rb +0 -150
- data/spec/routing/routing_spec.rb +0 -340
- data/spec/spec_helper.rb +0 -90
- data/spec/support/ci/install_phantomjs +0 -7
- data/spec/support/hint_examples.rb +0 -28
- data/spec/support/test_tweaks.rb +0 -31
- data/spec/support/transformation_examples.rb +0 -179
- data/spec/tasks/helpers_spec.rb +0 -217
- data/spec/views/admin/pictures/show_spec.rb +0 -43
- data/spec/views/essences/essence_boolean_editor_spec.rb +0 -32
- data/spec/views/essences/essence_boolean_view_spec.rb +0 -23
- data/spec/views/essences/essence_date_view_spec.rb +0 -38
- data/spec/views/essences/essence_file_editor_spec.rb +0 -59
- data/spec/views/essences/essence_file_view_spec.rb +0 -77
- data/spec/views/essences/essence_html_view_spec.rb +0 -22
- data/spec/views/essences/essence_link_view_spec.rb +0 -41
- data/spec/views/essences/essence_picture_editor_spec.rb +0 -80
- data/spec/views/essences/essence_picture_view_spec.rb +0 -128
- data/spec/views/essences/essence_richtext_view_spec.rb +0 -32
- data/spec/views/essences/essence_select_view_spec.rb +0 -11
- data/spec/views/essences/essence_text_view_spec.rb +0 -51
|
@@ -1,862 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
require 'spec_helper'
|
|
3
|
-
|
|
4
|
-
module Alchemy
|
|
5
|
-
describe Element do
|
|
6
|
-
# to prevent memoization
|
|
7
|
-
before { Element.instance_variable_set("@definitions", nil) }
|
|
8
|
-
|
|
9
|
-
# ClassMethods
|
|
10
|
-
|
|
11
|
-
describe '.new_from_scratch' do
|
|
12
|
-
it "should initialize an element by name from scratch" do
|
|
13
|
-
el = Element.new_from_scratch(name: 'article')
|
|
14
|
-
expect(el).to be_valid
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it "should raise an error if the given name is not defined in the elements.yml" do
|
|
18
|
-
expect {
|
|
19
|
-
Element.new_from_scratch(name: 'foobar')
|
|
20
|
-
}.to raise_error(ElementDefinitionError)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "should take the first part of an given name containing a hash (#)" do
|
|
24
|
-
el = Element.new_from_scratch(name: 'article#header')
|
|
25
|
-
expect(el.name).to eq("article")
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it "should merge given attributes into defined ones" do
|
|
29
|
-
el = Element.new_from_scratch(name: 'article', page_id: 1)
|
|
30
|
-
expect(el.page_id).to eq(1)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "should not have forbidden attributes from definition" do
|
|
34
|
-
el = Element.new_from_scratch(name: 'article')
|
|
35
|
-
expect(el.contents).to eq([])
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
describe '.copy' do
|
|
40
|
-
subject { Element.copy(element) }
|
|
41
|
-
|
|
42
|
-
let(:element) do
|
|
43
|
-
create(:alchemy_element, create_contents_after_create: true, tag_list: 'red, yellow')
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "should not create contents from scratch" do
|
|
47
|
-
expect(subject.contents.count).to eq(element.contents.count)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
context 'with differences' do
|
|
51
|
-
subject(:copy) { Element.copy(element, {name: 'foobar'}) }
|
|
52
|
-
|
|
53
|
-
it "should create a new record with all attributes of source except given differences" do
|
|
54
|
-
expect(copy.name).to eq('foobar')
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
it "should make copies of all contents of source" do
|
|
59
|
-
expect(subject.contents).not_to be_empty
|
|
60
|
-
expect(subject.contents.pluck(:id)).not_to eq(element.contents.pluck(:id))
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it "the copy should include source element tags" do
|
|
64
|
-
expect(subject.tag_list).to eq(element.tag_list)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
context 'with nested elements' do
|
|
68
|
-
let(:element) do
|
|
69
|
-
create(:alchemy_element, :with_nestable_elements, {
|
|
70
|
-
create_contents_after_create: true,
|
|
71
|
-
tag_list: 'red, yellow',
|
|
72
|
-
page: create(:alchemy_page)
|
|
73
|
-
})
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
before do
|
|
77
|
-
element.nested_elements << create(:alchemy_element, name: 'slide')
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
it "should copy nested elements" do
|
|
81
|
-
expect(subject.nested_elements).to_not be_empty
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
context 'copy to new page' do
|
|
85
|
-
let(:new_page) { create(:alchemy_page) }
|
|
86
|
-
|
|
87
|
-
subject(:new_element) do
|
|
88
|
-
Element.copy(element, {page_id: new_page.id})
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it "should set page id to new page's id" do
|
|
92
|
-
new_element.nested_elements.each do |nested_element|
|
|
93
|
-
expect(nested_element.page_id).to eq(new_page.id)
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
context 'copy to new cell' do
|
|
99
|
-
let(:new_cell) { create(:alchemy_cell) }
|
|
100
|
-
|
|
101
|
-
subject(:new_element) do
|
|
102
|
-
Element.copy(element, {cell_id: new_cell.id})
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
it "should set cell id to new cell's id" do
|
|
106
|
-
new_element.nested_elements.each do |nested_element|
|
|
107
|
-
expect(nested_element.cell_id).to eq(new_cell.id)
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
describe '.definitions' do
|
|
115
|
-
it "should allow erb generated elements" do
|
|
116
|
-
expect(Element.definitions.collect { |el| el['name'] }).to include('erb_element')
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
context "without existing yml files" do
|
|
120
|
-
before { allow(File).to receive(:exist?).and_return(false) }
|
|
121
|
-
|
|
122
|
-
it "should raise an error" do
|
|
123
|
-
expect { Element.definitions }.to raise_error(LoadError)
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
context "without any definitions in elements.yml" do
|
|
128
|
-
# Yes, YAML.load returns false if an empty file exists.
|
|
129
|
-
before { allow(YAML).to receive(:load).and_return(false) }
|
|
130
|
-
|
|
131
|
-
it "should return an empty array" do
|
|
132
|
-
expect(Element.definitions).to eq([])
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
describe '.display_name_for' do
|
|
138
|
-
it "should return the translation for the given name" do
|
|
139
|
-
expect(Alchemy).to receive(:t).with('subheadline', scope: "element_names", default: 'Subheadline').and_return('Überschrift')
|
|
140
|
-
expect(Element.display_name_for('subheadline')).to eq('Überschrift')
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
it "should return the humanized name if no translation found" do
|
|
144
|
-
expect(Element.display_name_for('not_existing_one')).to eq('Not existing one')
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
describe '.excluded' do
|
|
149
|
-
it "should return all elements but excluded ones" do
|
|
150
|
-
create(:alchemy_element, name: 'article')
|
|
151
|
-
create(:alchemy_element, name: 'article')
|
|
152
|
-
excluded = create(:alchemy_element, name: 'claim')
|
|
153
|
-
expect(Element.excluded(['claim'])).not_to include(excluded)
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
describe '.named' do
|
|
158
|
-
it "should return all elements by name" do
|
|
159
|
-
element_1 = create(:alchemy_element, name: 'article')
|
|
160
|
-
element_2 = create(:alchemy_element, name: 'headline')
|
|
161
|
-
elements = Element.named(['article'])
|
|
162
|
-
expect(elements).to include(element_1)
|
|
163
|
-
expect(elements).to_not include(element_2)
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
describe '.not_in_cell' do
|
|
168
|
-
it "should return all elements that are not in a cell" do
|
|
169
|
-
Element.delete_all
|
|
170
|
-
create(:alchemy_element, cell_id: 6)
|
|
171
|
-
create(:alchemy_element, cell_id: nil)
|
|
172
|
-
expect(Element.not_in_cell.size).to eq(1)
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
describe '.published' do
|
|
177
|
-
it "should return all public elements" do
|
|
178
|
-
element_1 = create(:alchemy_element, public: true)
|
|
179
|
-
element_2 = create(:alchemy_element, public: false)
|
|
180
|
-
elements = Element.published
|
|
181
|
-
expect(elements).to include(element_1)
|
|
182
|
-
expect(elements).to_not include(element_2)
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
describe '.folded' do
|
|
187
|
-
it "returns all folded elements" do
|
|
188
|
-
element_1 = create(:alchemy_element, folded: true)
|
|
189
|
-
element_2 = create(:alchemy_element, folded: false)
|
|
190
|
-
elements = Element.folded
|
|
191
|
-
expect(elements).to include(element_1)
|
|
192
|
-
expect(elements).to_not include(element_2)
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
describe '.expanded' do
|
|
197
|
-
it "returns all expanded elements" do
|
|
198
|
-
element_1 = create(:alchemy_element, folded: false)
|
|
199
|
-
element_2 = create(:alchemy_element, folded: true)
|
|
200
|
-
elements = Element.expanded
|
|
201
|
-
expect(elements).to include(element_1)
|
|
202
|
-
expect(elements).to_not include(element_2)
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
context 'trash' do
|
|
207
|
-
let(:element) { create(:alchemy_element, page_id: 1) }
|
|
208
|
-
|
|
209
|
-
describe '.not_trashed' do
|
|
210
|
-
before { element }
|
|
211
|
-
|
|
212
|
-
it "should return a collection of not trashed elements" do
|
|
213
|
-
expect(Element.not_trashed.to_a).to eq([element])
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
describe ".trashed" do
|
|
218
|
-
before { element.trash! }
|
|
219
|
-
|
|
220
|
-
it "should return a collection of trashed elements" do
|
|
221
|
-
expect(Element.trashed.to_a).to eq([element])
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
describe '.all_from_clipboard_for_page' do
|
|
227
|
-
let(:element_1) { build_stubbed(:alchemy_element) }
|
|
228
|
-
let(:element_2) { build_stubbed(:alchemy_element, name: 'news') }
|
|
229
|
-
let(:page) { build_stubbed(:alchemy_page, :public) }
|
|
230
|
-
let(:clipboard) { [{'id' => element_1.id.to_s}, {'id' => element_2.id.to_s}] }
|
|
231
|
-
|
|
232
|
-
before do
|
|
233
|
-
allow(Element).to receive(:all_from_clipboard).and_return([element_1, element_2])
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
it "return all elements from clipboard that could be placed on page" do
|
|
237
|
-
elements = Element.all_from_clipboard_for_page(clipboard, page)
|
|
238
|
-
expect(elements).to eq([element_1])
|
|
239
|
-
expect(elements).not_to eq([element_2])
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
context "page nil" do
|
|
243
|
-
it "returns empty array" do
|
|
244
|
-
expect(Element.all_from_clipboard_for_page(clipboard, nil)).to eq([])
|
|
245
|
-
end
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
context "clipboard nil" do
|
|
249
|
-
it "returns empty array" do
|
|
250
|
-
expect(Element.all_from_clipboard_for_page(nil, page)).to eq([])
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
# InstanceMethods
|
|
256
|
-
|
|
257
|
-
describe '#all_contents_by_type' do
|
|
258
|
-
let(:element) { create(:alchemy_element, create_contents_after_create: true) }
|
|
259
|
-
let(:expected_contents) { element.contents.essence_texts }
|
|
260
|
-
|
|
261
|
-
context "with namespaced essence type" do
|
|
262
|
-
subject { element.all_contents_by_type('Alchemy::EssenceText') }
|
|
263
|
-
it { is_expected.not_to be_empty }
|
|
264
|
-
it('should return the correct list of essences') { is_expected.to eq(expected_contents) }
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
context "without namespaced essence type" do
|
|
268
|
-
subject { element.all_contents_by_type('EssenceText') }
|
|
269
|
-
it { is_expected.not_to be_empty }
|
|
270
|
-
it('should return the correct list of essences') { is_expected.to eq(expected_contents) }
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
describe '#available_page_cell_names' do
|
|
275
|
-
let(:page) { create(:alchemy_page, :public) }
|
|
276
|
-
let(:element) { create(:alchemy_element, page: page) }
|
|
277
|
-
|
|
278
|
-
context "with page having cells defining the correct elements" do
|
|
279
|
-
before do
|
|
280
|
-
allow(Cell).to receive(:definitions).and_return([
|
|
281
|
-
{'name' => 'header', 'elements' => ['article', 'headline']},
|
|
282
|
-
{'name' => 'footer', 'elements' => ['article', 'text']},
|
|
283
|
-
{'name' => 'sidebar', 'elements' => ['teaser']}
|
|
284
|
-
])
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
it "should return a list of all cells from given page this element could be placed in" do
|
|
288
|
-
create(:alchemy_cell, name: 'header', page: page)
|
|
289
|
-
create(:alchemy_cell, name: 'footer', page: page)
|
|
290
|
-
create(:alchemy_cell, name: 'sidebar', page: page)
|
|
291
|
-
expect(element.available_page_cell_names(page)).to include('header')
|
|
292
|
-
expect(element.available_page_cell_names(page)).to include('footer')
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
context "but without any cells" do
|
|
296
|
-
it "should return the 'nil cell'" do
|
|
297
|
-
expect(element.available_page_cell_names(page)).to eq(['for_other_elements'])
|
|
298
|
-
end
|
|
299
|
-
end
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
context "with page having cells defining the wrong elements" do
|
|
303
|
-
before do
|
|
304
|
-
allow(Cell).to receive(:definitions).and_return([
|
|
305
|
-
{'name' => 'header', 'elements' => ['download', 'headline']},
|
|
306
|
-
{'name' => 'footer', 'elements' => ['contactform', 'text']},
|
|
307
|
-
{'name' => 'sidebar', 'elements' => ['teaser']}
|
|
308
|
-
])
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
it "should return the 'nil cell'" do
|
|
312
|
-
create(:alchemy_cell, name: 'header', page: page)
|
|
313
|
-
create(:alchemy_cell, name: 'footer', page: page)
|
|
314
|
-
create(:alchemy_cell, name: 'sidebar', page: page)
|
|
315
|
-
expect(element.available_page_cell_names(page)).to eq(['for_other_elements'])
|
|
316
|
-
end
|
|
317
|
-
end
|
|
318
|
-
end
|
|
319
|
-
|
|
320
|
-
describe '#content_by_type' do
|
|
321
|
-
before(:each) do
|
|
322
|
-
@element = create(:alchemy_element, name: 'headline')
|
|
323
|
-
@content = @element.contents.first
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
context "with namespaced essence type" do
|
|
327
|
-
it "should return content by passing a essence type" do
|
|
328
|
-
expect(@element.content_by_type('Alchemy::EssenceText')).to eq(@content)
|
|
329
|
-
end
|
|
330
|
-
end
|
|
331
|
-
|
|
332
|
-
context "without namespaced essence type" do
|
|
333
|
-
it "should return content by passing a essence type" do
|
|
334
|
-
expect(@element.content_by_type('EssenceText')).to eq(@content)
|
|
335
|
-
end
|
|
336
|
-
end
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
describe '#display_name' do
|
|
340
|
-
let(:element) { Element.new(name: 'article') }
|
|
341
|
-
|
|
342
|
-
it "should call .display_name_for" do
|
|
343
|
-
expect(Element).to receive(:display_name_for).with(element.name)
|
|
344
|
-
element.display_name
|
|
345
|
-
end
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
describe '#essence_errors' do
|
|
349
|
-
let(:element) { Element.new(name: 'article') }
|
|
350
|
-
let(:content) { Content.new(name: 'headline') }
|
|
351
|
-
let(:essence) { EssenceText.new(body: '') }
|
|
352
|
-
|
|
353
|
-
before do
|
|
354
|
-
allow(element).to receive(:contents) { [content] }
|
|
355
|
-
allow(content).to receive(:essence) { essence }
|
|
356
|
-
allow(content).to receive(:essence_validation_failed?) { true }
|
|
357
|
-
allow(essence).to receive(:validation_errors) { 'Cannot be blank' }
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
it "returns hash with essence errors" do
|
|
361
|
-
expect(element.essence_errors).to eq({'headline' => 'Cannot be blank'})
|
|
362
|
-
end
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
describe '#essence_error_messages' do
|
|
366
|
-
let(:element) { Element.new(name: 'article') }
|
|
367
|
-
|
|
368
|
-
it "should return the translation with the translated content label" do
|
|
369
|
-
expect(Alchemy).to receive(:t)
|
|
370
|
-
.with('content_names.content', default: 'Content')
|
|
371
|
-
.and_return('Content')
|
|
372
|
-
expect(Alchemy).to receive(:t)
|
|
373
|
-
.with('content', scope: "content_names.article", default: 'Content')
|
|
374
|
-
.and_return('Contenido')
|
|
375
|
-
expect(Alchemy).to receive(:t)
|
|
376
|
-
.with('article.content.invalid', {
|
|
377
|
-
scope: "content_validations",
|
|
378
|
-
default: [:"fields.content.invalid", :"errors.invalid"],
|
|
379
|
-
field: "Contenido"})
|
|
380
|
-
expect(element).to receive(:essence_errors)
|
|
381
|
-
.and_return({'content' => [:invalid]})
|
|
382
|
-
|
|
383
|
-
element.essence_error_messages
|
|
384
|
-
end
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
describe '#display_name_with_preview_text' do
|
|
388
|
-
let(:element) { build_stubbed(:alchemy_element, name: 'Foo') }
|
|
389
|
-
|
|
390
|
-
it "returns a string with display name and preview text" do
|
|
391
|
-
allow(element).to receive(:preview_text).and_return('Fula')
|
|
392
|
-
expect(element.display_name_with_preview_text).to eq("Foo: Fula")
|
|
393
|
-
end
|
|
394
|
-
end
|
|
395
|
-
|
|
396
|
-
describe '#dom_id' do
|
|
397
|
-
let(:element) { build_stubbed(:alchemy_element) }
|
|
398
|
-
|
|
399
|
-
it "returns an string from element name and id" do
|
|
400
|
-
expect(element.dom_id).to eq("#{element.name}_#{element.id}")
|
|
401
|
-
end
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
describe '#preview_text' do
|
|
405
|
-
let(:element) { build_stubbed(:alchemy_element) }
|
|
406
|
-
|
|
407
|
-
let(:content) do
|
|
408
|
-
mock_model(Content, preview_text: 'Content 1', preview_content?: false)
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
let(:content_2) do
|
|
412
|
-
mock_model(Content, preview_text: 'Content 2', preview_content?: false)
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
let(:preview_content) do
|
|
416
|
-
mock_model(Content, preview_text: 'Preview Content', preview_content?: true)
|
|
417
|
-
end
|
|
418
|
-
|
|
419
|
-
context "without a content marked as preview" do
|
|
420
|
-
let(:contents) { [content, content_2] }
|
|
421
|
-
|
|
422
|
-
before do
|
|
423
|
-
allow(element).to receive(:contents).and_return(contents)
|
|
424
|
-
end
|
|
425
|
-
|
|
426
|
-
it "returns the preview text of first content found" do
|
|
427
|
-
expect(content).to receive(:preview_text).with(30)
|
|
428
|
-
element.preview_text
|
|
429
|
-
end
|
|
430
|
-
end
|
|
431
|
-
|
|
432
|
-
context "with a content marked as preview" do
|
|
433
|
-
let(:contents) { [content, preview_content] }
|
|
434
|
-
|
|
435
|
-
before do
|
|
436
|
-
allow(element).to receive(:contents).and_return(contents)
|
|
437
|
-
end
|
|
438
|
-
|
|
439
|
-
it "should return the preview_text of this content" do
|
|
440
|
-
expect(preview_content).to receive(:preview_text).with(30)
|
|
441
|
-
element.preview_text
|
|
442
|
-
end
|
|
443
|
-
end
|
|
444
|
-
|
|
445
|
-
context "without any contents present" do
|
|
446
|
-
before do
|
|
447
|
-
allow(element).to receive(:contents).and_return([])
|
|
448
|
-
end
|
|
449
|
-
|
|
450
|
-
it "should return nil" do
|
|
451
|
-
expect(element.preview_text).to be_nil
|
|
452
|
-
end
|
|
453
|
-
end
|
|
454
|
-
|
|
455
|
-
context 'with nested elements' do
|
|
456
|
-
let(:element) do
|
|
457
|
-
build_stubbed(:alchemy_element, :with_nestable_elements)
|
|
458
|
-
end
|
|
459
|
-
|
|
460
|
-
let(:nested_element) do
|
|
461
|
-
build_stubbed(:alchemy_element, name: 'slide')
|
|
462
|
-
end
|
|
463
|
-
|
|
464
|
-
before do
|
|
465
|
-
allow(nested_element).to receive(:contents) { [content_2] }
|
|
466
|
-
allow(element).to receive(:nested_elements) { [nested_element] }
|
|
467
|
-
end
|
|
468
|
-
|
|
469
|
-
context 'when parent element has contents' do
|
|
470
|
-
before do
|
|
471
|
-
allow(element).to receive(:contents) { [content] }
|
|
472
|
-
end
|
|
473
|
-
|
|
474
|
-
it 'returns the preview text from the parent element' do
|
|
475
|
-
expect(content).to receive(:preview_text)
|
|
476
|
-
expect(element.preview_text)
|
|
477
|
-
end
|
|
478
|
-
end
|
|
479
|
-
|
|
480
|
-
context 'when parent element has no contents but nestable element has' do
|
|
481
|
-
before do
|
|
482
|
-
allow(element).to receive(:contents) { [] }
|
|
483
|
-
allow(nested_element).to receive(:contents) { [content_2] }
|
|
484
|
-
end
|
|
485
|
-
|
|
486
|
-
it 'returns the preview text from the first nested element' do
|
|
487
|
-
expect(content_2).to receive(:preview_text)
|
|
488
|
-
expect(element.preview_text)
|
|
489
|
-
end
|
|
490
|
-
end
|
|
491
|
-
end
|
|
492
|
-
end
|
|
493
|
-
|
|
494
|
-
context 'previous and next elements.' do
|
|
495
|
-
let(:page) { create(:alchemy_page, :language_root) }
|
|
496
|
-
|
|
497
|
-
before(:each) do
|
|
498
|
-
@element1 = create(:alchemy_element, page: page, name: 'headline')
|
|
499
|
-
@element2 = create(:alchemy_element, page: page)
|
|
500
|
-
@element3 = create(:alchemy_element, page: page, name: 'text')
|
|
501
|
-
end
|
|
502
|
-
|
|
503
|
-
describe '#prev' do
|
|
504
|
-
it "should return previous element on same page" do
|
|
505
|
-
expect(@element3.prev).to eq(@element2)
|
|
506
|
-
end
|
|
507
|
-
|
|
508
|
-
context "with name as parameter" do
|
|
509
|
-
it "should return previous of this kind" do
|
|
510
|
-
expect(@element3.prev('headline')).to eq(@element1)
|
|
511
|
-
end
|
|
512
|
-
end
|
|
513
|
-
end
|
|
514
|
-
|
|
515
|
-
describe '#next' do
|
|
516
|
-
it "should return next element on same page" do
|
|
517
|
-
expect(@element2.next).to eq(@element3)
|
|
518
|
-
end
|
|
519
|
-
|
|
520
|
-
context "with name as parameter" do
|
|
521
|
-
it "should return next of this kind" do
|
|
522
|
-
expect(@element1.next('text')).to eq(@element3)
|
|
523
|
-
end
|
|
524
|
-
end
|
|
525
|
-
end
|
|
526
|
-
end
|
|
527
|
-
|
|
528
|
-
context 'retrieving contents, essences and ingredients' do
|
|
529
|
-
let(:element) { create(:alchemy_element, name: 'news', create_contents_after_create: true) }
|
|
530
|
-
|
|
531
|
-
it "should return an ingredient by name" do
|
|
532
|
-
expect(element.ingredient('news_headline')).to eq(EssenceText.first.ingredient)
|
|
533
|
-
end
|
|
534
|
-
|
|
535
|
-
it "should return the content for rss title" do
|
|
536
|
-
expect(element.content_for_rss_title).to eq(element.contents.find_by_name('news_headline'))
|
|
537
|
-
end
|
|
538
|
-
|
|
539
|
-
it "should return the content for rss descdefinitionription" do
|
|
540
|
-
expect(element.content_for_rss_description).to eq(element.contents.find_by_name('body'))
|
|
541
|
-
end
|
|
542
|
-
|
|
543
|
-
context 'if no content is defined as rss title' do
|
|
544
|
-
before { expect(element).to receive(:content_definitions).and_return([]) }
|
|
545
|
-
|
|
546
|
-
it "should return nil" do
|
|
547
|
-
expect(element.content_for_rss_title).to be_nil
|
|
548
|
-
end
|
|
549
|
-
end
|
|
550
|
-
|
|
551
|
-
context 'if no content is defined as rss description' do
|
|
552
|
-
before { expect(element).to receive(:content_definitions).and_return([]) }
|
|
553
|
-
|
|
554
|
-
it "should return nil" do
|
|
555
|
-
expect(element.content_for_rss_description).to be_nil
|
|
556
|
-
end
|
|
557
|
-
end
|
|
558
|
-
end
|
|
559
|
-
|
|
560
|
-
describe '#update_contents' do
|
|
561
|
-
subject { element.update_contents(params) }
|
|
562
|
-
|
|
563
|
-
let(:page) { build_stubbed(:alchemy_page) }
|
|
564
|
-
let(:element) { build_stubbed(:alchemy_element, page: page) }
|
|
565
|
-
let(:content1) { double(:content, id: 1) }
|
|
566
|
-
let(:content2) { double(:content, id: 2) }
|
|
567
|
-
|
|
568
|
-
before { allow(element).to receive(:contents).and_return([content1]) }
|
|
569
|
-
|
|
570
|
-
context "with attributes hash is nil" do
|
|
571
|
-
let(:params) { nil }
|
|
572
|
-
it { is_expected.to be_truthy }
|
|
573
|
-
end
|
|
574
|
-
|
|
575
|
-
context "with valid attributes hash" do
|
|
576
|
-
let(:params) { {content1.id.to_s => {body: 'Title'}} }
|
|
577
|
-
|
|
578
|
-
context 'when certain content is not part of the attributes hash (cause it was not filled by the user)' do
|
|
579
|
-
before do
|
|
580
|
-
allow(element).to receive(:contents).and_return([content1, content2])
|
|
581
|
-
end
|
|
582
|
-
|
|
583
|
-
it 'does not try to update that content' do
|
|
584
|
-
expect(content1).to receive(:update_essence).with({body: 'Title'}).and_return(true)
|
|
585
|
-
expect(content2).to_not receive(:update_essence)
|
|
586
|
-
subject
|
|
587
|
-
end
|
|
588
|
-
end
|
|
589
|
-
|
|
590
|
-
context 'with passing validations' do
|
|
591
|
-
before do
|
|
592
|
-
expect(content1).to receive(:update_essence).with({body: 'Title'}).and_return(true)
|
|
593
|
-
end
|
|
594
|
-
|
|
595
|
-
it { is_expected.to be_truthy }
|
|
596
|
-
|
|
597
|
-
it "does not add errors" do
|
|
598
|
-
subject
|
|
599
|
-
expect(element.errors).to be_empty
|
|
600
|
-
end
|
|
601
|
-
end
|
|
602
|
-
|
|
603
|
-
context 'with failing validations' do
|
|
604
|
-
it "adds error and returns false" do
|
|
605
|
-
expect(content1).to receive(:update_essence).with({body: 'Title'}).and_return(false)
|
|
606
|
-
is_expected.to be_falsey
|
|
607
|
-
expect(element.errors).not_to be_empty
|
|
608
|
-
end
|
|
609
|
-
end
|
|
610
|
-
end
|
|
611
|
-
end
|
|
612
|
-
|
|
613
|
-
describe '.after_update' do
|
|
614
|
-
let(:page) { create(:alchemy_page) }
|
|
615
|
-
let(:element) { create(:alchemy_element, page: page) }
|
|
616
|
-
let(:now) { Time.current }
|
|
617
|
-
|
|
618
|
-
before do
|
|
619
|
-
allow(Time).to receive(:now).and_return(now)
|
|
620
|
-
end
|
|
621
|
-
|
|
622
|
-
context 'with touchable pages' do
|
|
623
|
-
let(:locker) { mock_model('DummyUser') }
|
|
624
|
-
let(:pages) { [page] }
|
|
625
|
-
|
|
626
|
-
before do
|
|
627
|
-
expect(Alchemy.user_class).to receive(:stamper).at_least(:once).and_return(locker.id)
|
|
628
|
-
end
|
|
629
|
-
|
|
630
|
-
it "updates page timestamps" do
|
|
631
|
-
expect(element).to receive(:touchable_pages).and_return(pages)
|
|
632
|
-
expect(pages).to receive(:update_all).with({updated_at: now, updater_id: locker.id})
|
|
633
|
-
element.save
|
|
634
|
-
end
|
|
635
|
-
|
|
636
|
-
it "updates page userstamps" do
|
|
637
|
-
element.save
|
|
638
|
-
page.reload
|
|
639
|
-
expect(page.updater_id).to eq(locker.id)
|
|
640
|
-
end
|
|
641
|
-
end
|
|
642
|
-
|
|
643
|
-
context 'with cell associated' do
|
|
644
|
-
let(:cell) { mock_model('Cell') }
|
|
645
|
-
|
|
646
|
-
before do
|
|
647
|
-
expect(element).to receive(:cell).at_least(:once).and_return(cell)
|
|
648
|
-
end
|
|
649
|
-
|
|
650
|
-
it "updates timestamp of cell" do
|
|
651
|
-
expect(element.cell).to receive(:touch)
|
|
652
|
-
element.save
|
|
653
|
-
end
|
|
654
|
-
end
|
|
655
|
-
|
|
656
|
-
context 'without cell associated' do
|
|
657
|
-
it "does not update timestamp of cell" do
|
|
658
|
-
expect { element.save }.to_not raise_error
|
|
659
|
-
end
|
|
660
|
-
end
|
|
661
|
-
end
|
|
662
|
-
|
|
663
|
-
describe '#taggable?' do
|
|
664
|
-
let(:element) { build(:alchemy_element) }
|
|
665
|
-
|
|
666
|
-
context "definition has 'taggable' key with true value" do
|
|
667
|
-
it "should return true" do
|
|
668
|
-
expect(element).to receive(:definition).and_return({
|
|
669
|
-
'name' => 'article',
|
|
670
|
-
'taggable' => true
|
|
671
|
-
})
|
|
672
|
-
expect(element.taggable?).to be_truthy
|
|
673
|
-
end
|
|
674
|
-
end
|
|
675
|
-
|
|
676
|
-
context "definition has 'taggable' key with foo value" do
|
|
677
|
-
it "should return false" do
|
|
678
|
-
expect(element).to receive(:definition).and_return({
|
|
679
|
-
'name' => 'article',
|
|
680
|
-
'taggable' => 'foo'
|
|
681
|
-
})
|
|
682
|
-
expect(element.taggable?).to be_falsey
|
|
683
|
-
end
|
|
684
|
-
end
|
|
685
|
-
|
|
686
|
-
context "definition has no 'taggable' key" do
|
|
687
|
-
it "should return false" do
|
|
688
|
-
expect(element).to receive(:definition).and_return({
|
|
689
|
-
'name' => 'article'
|
|
690
|
-
})
|
|
691
|
-
expect(element.taggable?).to be_falsey
|
|
692
|
-
end
|
|
693
|
-
end
|
|
694
|
-
end
|
|
695
|
-
|
|
696
|
-
describe '#trash!' do
|
|
697
|
-
let(:element) { create(:alchemy_element, page_id: 1, cell_id: 1) }
|
|
698
|
-
let(:trashed_element) { element.trash!; element }
|
|
699
|
-
subject { trashed_element }
|
|
700
|
-
|
|
701
|
-
it { is_expected.not_to be_public }
|
|
702
|
-
it { is_expected.to be_folded }
|
|
703
|
-
|
|
704
|
-
describe '#position' do
|
|
705
|
-
subject { super().position }
|
|
706
|
-
it { is_expected.to be_nil }
|
|
707
|
-
end
|
|
708
|
-
specify { expect { element.trash! }.to_not change(element, :page_id) }
|
|
709
|
-
specify { expect { element.trash! }.to_not change(element, :cell_id) }
|
|
710
|
-
|
|
711
|
-
context "with already one trashed element on the same page" do
|
|
712
|
-
let(:element_2) { create(:alchemy_element, page_id: 1) }
|
|
713
|
-
|
|
714
|
-
before do
|
|
715
|
-
trashed_element
|
|
716
|
-
element_2
|
|
717
|
-
end
|
|
718
|
-
|
|
719
|
-
it "it should be possible to trash another" do
|
|
720
|
-
element_2.trash!
|
|
721
|
-
expect(Element.trashed.to_a).to include(trashed_element, element_2)
|
|
722
|
-
end
|
|
723
|
-
end
|
|
724
|
-
end
|
|
725
|
-
|
|
726
|
-
describe "#to_partial_path" do
|
|
727
|
-
it "should return a String in the format of 'alchemy/elements/#{name}_view'" do
|
|
728
|
-
expect(Element.new(name: 'mock').to_partial_path).to eq('alchemy/elements/mock_view')
|
|
729
|
-
end
|
|
730
|
-
end
|
|
731
|
-
|
|
732
|
-
describe '#cache_key' do
|
|
733
|
-
let(:page) { stub_model(Page, published_at: Time.current - 1.week) }
|
|
734
|
-
let(:element) { stub_model(Element, page: page, updated_at: Time.current) }
|
|
735
|
-
|
|
736
|
-
subject { element.cache_key }
|
|
737
|
-
|
|
738
|
-
before do
|
|
739
|
-
expect(Page).to receive(:current_preview).and_return(preview)
|
|
740
|
-
end
|
|
741
|
-
|
|
742
|
-
context "when current page rendered in preview mode" do
|
|
743
|
-
let(:preview) { page }
|
|
744
|
-
|
|
745
|
-
it { is_expected.to eq("alchemy/elements/#{element.id}-#{element.updated_at}") }
|
|
746
|
-
end
|
|
747
|
-
|
|
748
|
-
context "when current page not in preview mode" do
|
|
749
|
-
let(:preview) { nil }
|
|
750
|
-
|
|
751
|
-
it { is_expected.to eq("alchemy/elements/#{element.id}-#{page.published_at}") }
|
|
752
|
-
end
|
|
753
|
-
end
|
|
754
|
-
|
|
755
|
-
it_behaves_like "having a hint" do
|
|
756
|
-
let(:subject) { Element.new }
|
|
757
|
-
end
|
|
758
|
-
|
|
759
|
-
describe "#nestable_elements" do
|
|
760
|
-
let(:element) { Element.new }
|
|
761
|
-
|
|
762
|
-
subject { element.nestable_elements }
|
|
763
|
-
|
|
764
|
-
context 'with nestable_elements defined' do
|
|
765
|
-
before do
|
|
766
|
-
allow(element).to receive(:definition) do
|
|
767
|
-
{
|
|
768
|
-
'nestable_elements' => %w(news article)
|
|
769
|
-
}
|
|
770
|
-
end
|
|
771
|
-
end
|
|
772
|
-
|
|
773
|
-
it 'returns an array containing all available nested element names' do
|
|
774
|
-
is_expected.to eq %w(news article)
|
|
775
|
-
end
|
|
776
|
-
end
|
|
777
|
-
|
|
778
|
-
context 'without nestable_elements defined' do
|
|
779
|
-
before do
|
|
780
|
-
allow(element).to receive(:definition) do
|
|
781
|
-
{}
|
|
782
|
-
end
|
|
783
|
-
end
|
|
784
|
-
|
|
785
|
-
it 'returns an empty array' do
|
|
786
|
-
is_expected.to eq []
|
|
787
|
-
end
|
|
788
|
-
end
|
|
789
|
-
end
|
|
790
|
-
|
|
791
|
-
describe "#nested_elements" do
|
|
792
|
-
subject { element.nested_elements }
|
|
793
|
-
|
|
794
|
-
context 'with nestable_elements defined' do
|
|
795
|
-
let(:element) { create(:alchemy_element, :with_nestable_elements) }
|
|
796
|
-
|
|
797
|
-
before do
|
|
798
|
-
element.nested_elements << create(:alchemy_element, name: 'slide')
|
|
799
|
-
end
|
|
800
|
-
|
|
801
|
-
it 'returns an AR scope containing nested elements' do
|
|
802
|
-
expect(subject.count).to eq(1)
|
|
803
|
-
end
|
|
804
|
-
end
|
|
805
|
-
end
|
|
806
|
-
|
|
807
|
-
describe '#richtext_contents_ids' do
|
|
808
|
-
subject { element.richtext_contents_ids }
|
|
809
|
-
|
|
810
|
-
let(:element) { create(:alchemy_element, :with_contents, name: 'text') }
|
|
811
|
-
|
|
812
|
-
it { is_expected.to eq(element.content_ids) }
|
|
813
|
-
|
|
814
|
-
context 'for element with nested elements' do
|
|
815
|
-
let!(:element) do
|
|
816
|
-
create(:alchemy_element, :with_contents, name: 'text')
|
|
817
|
-
end
|
|
818
|
-
|
|
819
|
-
let!(:nested_element_1) do
|
|
820
|
-
create(:alchemy_element, :with_contents, {
|
|
821
|
-
name: 'text',
|
|
822
|
-
parent_element: element,
|
|
823
|
-
folded: false
|
|
824
|
-
})
|
|
825
|
-
end
|
|
826
|
-
|
|
827
|
-
let!(:nested_element_2) do
|
|
828
|
-
create(:alchemy_element, :with_contents, {
|
|
829
|
-
name: 'text',
|
|
830
|
-
parent_element: nested_element_1,
|
|
831
|
-
folded: false
|
|
832
|
-
})
|
|
833
|
-
end
|
|
834
|
-
|
|
835
|
-
let!(:folded_nested_element_3) do
|
|
836
|
-
create(:alchemy_element, :with_contents, {
|
|
837
|
-
name: 'text',
|
|
838
|
-
parent_element: nested_element_1,
|
|
839
|
-
folded: true
|
|
840
|
-
})
|
|
841
|
-
end
|
|
842
|
-
|
|
843
|
-
it 'includes all richtext contents from all expanded descendent elements' do
|
|
844
|
-
is_expected.to eq(
|
|
845
|
-
element.content_ids +
|
|
846
|
-
nested_element_1.content_ids +
|
|
847
|
-
nested_element_2.content_ids
|
|
848
|
-
)
|
|
849
|
-
end
|
|
850
|
-
end
|
|
851
|
-
end
|
|
852
|
-
|
|
853
|
-
context 'with parent element' do
|
|
854
|
-
let!(:parent_element) { create(:alchemy_element, :with_nestable_elements) }
|
|
855
|
-
let!(:element) { create(:alchemy_element, name: 'slide', parent_element: parent_element) }
|
|
856
|
-
|
|
857
|
-
it "touches parent after update" do
|
|
858
|
-
expect { element.update!(public: false) }.to change(parent_element, :updated_at)
|
|
859
|
-
end
|
|
860
|
-
end
|
|
861
|
-
end
|
|
862
|
-
end
|