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.
Files changed (269) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -2
  3. data/Gemfile +1 -0
  4. data/alchemy_cms.gemspec +6 -6
  5. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +0 -7
  6. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +4 -4
  7. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +51 -5
  8. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +0 -2
  9. data/app/assets/stylesheets/alchemy/elements.scss +2 -2
  10. data/app/controllers/alchemy/admin/elements_controller.rb +2 -0
  11. data/app/controllers/alchemy/admin/pages_controller.rb +11 -3
  12. data/app/controllers/alchemy/admin/pictures_controller.rb +1 -0
  13. data/app/models/alchemy/element.rb +3 -1
  14. data/app/models/alchemy/element/element_contents.rb +2 -7
  15. data/app/models/alchemy/element/presenters.rb +11 -4
  16. data/app/models/alchemy/page.rb +3 -1
  17. data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +0 -1
  18. data/app/views/alchemy/admin/contents/create.js.erb +0 -1
  19. data/app/views/alchemy/admin/elements/_element_header.html.erb +3 -1
  20. data/app/views/alchemy/admin/elements/order.js.erb +25 -10
  21. data/app/views/alchemy/admin/elements/update.js.erb +1 -2
  22. data/app/views/alchemy/admin/essence_files/assign.js.erb +0 -1
  23. data/app/views/alchemy/admin/essence_pictures/assign.js.erb +0 -1
  24. data/app/views/alchemy/admin/legacy_page_urls/create.js.erb +0 -1
  25. data/app/views/alchemy/admin/pages/destroy.js.erb +0 -1
  26. data/app/views/alchemy/admin/pages/update.js.erb +6 -4
  27. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +2 -1
  28. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -7
  29. data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +0 -1
  30. data/bin/alchemy +1 -1
  31. data/bin/rspec +3 -2
  32. data/bin/spring +6 -6
  33. data/config/alchemy/config.yml +6 -1
  34. data/lib/alchemy/seeder.rb +9 -3
  35. data/lib/alchemy/version.rb +1 -1
  36. metadata +6 -471
  37. data/spec/controllers/alchemy/admin/attachments_controller_spec.rb +0 -193
  38. data/spec/controllers/alchemy/admin/base_controller_spec.rb +0 -87
  39. data/spec/controllers/alchemy/admin/clipboard_controller_spec.rb +0 -60
  40. data/spec/controllers/alchemy/admin/contents_controller_spec.rb +0 -78
  41. data/spec/controllers/alchemy/admin/dashboard_controller_spec.rb +0 -144
  42. data/spec/controllers/alchemy/admin/elements_controller_spec.rb +0 -496
  43. data/spec/controllers/alchemy/admin/essence_files_controller_spec.rb +0 -76
  44. data/spec/controllers/alchemy/admin/essence_pictures_controller_spec.rb +0 -202
  45. data/spec/controllers/alchemy/admin/languages_controller_spec.rb +0 -73
  46. data/spec/controllers/alchemy/admin/layoutpages_controller_spec.rb +0 -21
  47. data/spec/controllers/alchemy/admin/pages_controller_spec.rb +0 -639
  48. data/spec/controllers/alchemy/admin/pictures_controller_spec.rb +0 -383
  49. data/spec/controllers/alchemy/admin/resources_controller_spec.rb +0 -81
  50. data/spec/controllers/alchemy/admin/tags_controller_spec.rb +0 -63
  51. data/spec/controllers/alchemy/admin/trash_controller_spec.rb +0 -67
  52. data/spec/controllers/alchemy/api/contents_controller_spec.rb +0 -125
  53. data/spec/controllers/alchemy/api/elements_controller_spec.rb +0 -124
  54. data/spec/controllers/alchemy/api/pages_controller_spec.rb +0 -167
  55. data/spec/controllers/alchemy/attachments_controller_spec.rb +0 -64
  56. data/spec/controllers/alchemy/base_controller_spec.rb +0 -106
  57. data/spec/controllers/alchemy/elements_controller_spec.rb +0 -48
  58. data/spec/controllers/alchemy/messages_controller_spec.rb +0 -204
  59. data/spec/controllers/alchemy/on_page_layout_mixin_spec.rb +0 -330
  60. data/spec/controllers/alchemy/pages_controller_spec.rb +0 -343
  61. data/spec/controllers/alchemy/pictures_controller_spec.rb +0 -415
  62. data/spec/dummy/Rakefile +0 -6
  63. data/spec/dummy/app/assets/javascripts/application.js +0 -13
  64. data/spec/dummy/app/assets/stylesheets/application.css +0 -15
  65. data/spec/dummy/app/controllers/admin/events_controller.rb +0 -3
  66. data/spec/dummy/app/controllers/application_controller.rb +0 -15
  67. data/spec/dummy/app/controllers/login_controller.rb +0 -5
  68. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  69. data/spec/dummy/app/mailers/.gitkeep +0 -0
  70. data/spec/dummy/app/models/ability.rb +0 -9
  71. data/spec/dummy/app/models/dummy_model.rb +0 -3
  72. data/spec/dummy/app/models/dummy_user.rb +0 -15
  73. data/spec/dummy/app/models/event.rb +0 -10
  74. data/spec/dummy/app/models/location.rb +0 -3
  75. data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_editor.html.erb +0 -11
  76. data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_view.html.erb +0 -31
  77. data/spec/dummy/app/views/alchemy/elements/_article_editor.html.erb +0 -6
  78. data/spec/dummy/app/views/alchemy/elements/_article_view.html.erb +0 -10
  79. data/spec/dummy/app/views/alchemy/elements/_bild_editor.html.erb +0 -3
  80. data/spec/dummy/app/views/alchemy/elements/_bild_view.html.erb +0 -5
  81. data/spec/dummy/app/views/alchemy/elements/_contactform_editor.html.erb +0 -6
  82. data/spec/dummy/app/views/alchemy/elements/_contactform_view.html.erb +0 -16
  83. data/spec/dummy/app/views/alchemy/elements/_download_editor.html.erb +0 -3
  84. data/spec/dummy/app/views/alchemy/elements/_download_view.html.erb +0 -5
  85. data/spec/dummy/app/views/alchemy/elements/_erb_element_editor.html.erb +0 -3
  86. data/spec/dummy/app/views/alchemy/elements/_erb_element_view.html.erb +0 -5
  87. data/spec/dummy/app/views/alchemy/elements/_header_editor.html.erb +0 -3
  88. data/spec/dummy/app/views/alchemy/elements/_header_view.html.erb +0 -5
  89. data/spec/dummy/app/views/alchemy/elements/_headline_editor.html.erb +0 -1
  90. data/spec/dummy/app/views/alchemy/elements/_headline_view.html.erb +0 -1
  91. data/spec/dummy/app/views/alchemy/elements/_news_editor.html.erb +0 -5
  92. data/spec/dummy/app/views/alchemy/elements/_news_view.html.erb +0 -11
  93. data/spec/dummy/app/views/alchemy/elements/_search_editor.html.erb +0 -1
  94. data/spec/dummy/app/views/alchemy/elements/_search_view.html.erb +0 -4
  95. data/spec/dummy/app/views/alchemy/elements/_slide_editor.html.erb +0 -3
  96. data/spec/dummy/app/views/alchemy/elements/_slide_view.html.erb +0 -5
  97. data/spec/dummy/app/views/alchemy/elements/_slider_editor.html.erb +0 -2
  98. data/spec/dummy/app/views/alchemy/elements/_slider_view.html.erb +0 -4
  99. data/spec/dummy/app/views/alchemy/elements/_text_editor.html.erb +0 -3
  100. data/spec/dummy/app/views/alchemy/elements/_text_view.html.erb +0 -5
  101. data/spec/dummy/app/views/alchemy/page_layouts/_standard.html.erb +0 -15
  102. data/spec/dummy/app/views/layouts/application.html.erb +0 -17
  103. data/spec/dummy/bin/bundle +0 -3
  104. data/spec/dummy/bin/rails +0 -4
  105. data/spec/dummy/bin/rake +0 -4
  106. data/spec/dummy/config.ru +0 -4
  107. data/spec/dummy/config/alchemy/cells.yml +0 -5
  108. data/spec/dummy/config/alchemy/elements.yml +0 -109
  109. data/spec/dummy/config/alchemy/page_layouts.yml +0 -32
  110. data/spec/dummy/config/application.rb +0 -32
  111. data/spec/dummy/config/boot.rb +0 -5
  112. data/spec/dummy/config/database.yml +0 -32
  113. data/spec/dummy/config/environment.rb +0 -5
  114. data/spec/dummy/config/environments/development.rb +0 -41
  115. data/spec/dummy/config/environments/production.rb +0 -77
  116. data/spec/dummy/config/environments/test.rb +0 -43
  117. data/spec/dummy/config/initializers/alchemy.rb +0 -3
  118. data/spec/dummy/config/initializers/assets.rb +0 -11
  119. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  120. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -3
  121. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  122. data/spec/dummy/config/initializers/inflections.rb +0 -16
  123. data/spec/dummy/config/initializers/mime_types.rb +0 -4
  124. data/spec/dummy/config/initializers/secret_token.rb +0 -12
  125. data/spec/dummy/config/initializers/session_store.rb +0 -3
  126. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  127. data/spec/dummy/config/locales/kl.yml +0 -2
  128. data/spec/dummy/config/routes.rb +0 -12
  129. data/spec/dummy/config/secrets.yml +0 -22
  130. data/spec/dummy/db/migrate/20121026104128_create_events.rb +0 -20
  131. data/spec/dummy/db/migrate/20130328101418_create_locations.rb +0 -9
  132. data/spec/dummy/db/migrate/20130827094554_alchemy_two_point_six.rb +0 -1
  133. data/spec/dummy/db/migrate/20130828121054_remove_do_not_index_from_alchemy_essence_texts.rb +0 -1
  134. data/spec/dummy/db/migrate/20130828121120_remove_do_not_index_from_alchemy_essence_richtexts.rb +0 -1
  135. data/spec/dummy/db/migrate/20130918201742_add_published_at_to_alchemy_pages.rb +0 -1
  136. data/spec/dummy/db/migrate/20131209225243_create_dummy_users.rb +0 -9
  137. data/spec/dummy/db/migrate/20150122213511_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb +0 -31
  138. data/spec/dummy/db/migrate/20150122213512_add_missing_unique_indices.acts_as_taggable_on_engine.rb +0 -20
  139. data/spec/dummy/db/migrate/20150122213513_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb +0 -15
  140. data/spec/dummy/db/migrate/20150122213514_add_missing_taggable_index.acts_as_taggable_on_engine.rb +0 -10
  141. data/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb +0 -7
  142. data/spec/dummy/db/migrate/20150608204610_add_parent_element_id_to_alchemy_elements.rb +0 -1
  143. data/spec/dummy/db/migrate/20150729151825_add_link_text_to_alchemy_essence_files.rb +0 -1
  144. data/spec/dummy/db/migrate/20150906195818_add_locale_to_alchemy_languages.rb +0 -1
  145. data/spec/dummy/db/schema.rb +0 -326
  146. data/spec/dummy/db/seeds.rb +0 -1
  147. data/spec/dummy/lib/assets/.gitkeep +0 -0
  148. data/spec/dummy/public/404.html +0 -67
  149. data/spec/dummy/public/422.html +0 -67
  150. data/spec/dummy/public/500.html +0 -66
  151. data/spec/dummy/public/favicon.ico +0 -0
  152. data/spec/dummy/spec/javascripts +0 -1
  153. data/spec/factories.rb +0 -13
  154. data/spec/features/admin/admin_layout_spec.rb +0 -14
  155. data/spec/features/admin/dashboard_spec.rb +0 -81
  156. data/spec/features/admin/edit_elements_feature_spec.rb +0 -36
  157. data/spec/features/admin/language_tree_feature_spec.rb +0 -32
  158. data/spec/features/admin/languages_features_spec.rb +0 -65
  159. data/spec/features/admin/legacy_page_url_management_spec.rb +0 -62
  160. data/spec/features/admin/link_overlay_spec.rb +0 -53
  161. data/spec/features/admin/locale_select_feature_spec.rb +0 -25
  162. data/spec/features/admin/modules_integration_spec.rb +0 -23
  163. data/spec/features/admin/navigation_feature_spec.rb +0 -22
  164. data/spec/features/admin/page_creation_feature_spec.rb +0 -51
  165. data/spec/features/admin/page_editing_feature_spec.rb +0 -135
  166. data/spec/features/admin/picture_library_integration_spec.rb +0 -62
  167. data/spec/features/admin/resources_integration_spec.rb +0 -128
  168. data/spec/features/admin/site_select_feature_spec.rb +0 -31
  169. data/spec/features/admin/tinymce_feature_spec.rb +0 -33
  170. data/spec/features/navigation_spec.rb +0 -9
  171. data/spec/features/page_feature_spec.rb +0 -186
  172. data/spec/features/page_redirects_spec.rb +0 -358
  173. data/spec/features/picture_security_spec.rb +0 -29
  174. data/spec/features/security_spec.rb +0 -24
  175. data/spec/features/translation_integration_spec.rb +0 -51
  176. data/spec/fixtures/500x500.png +0 -0
  177. data/spec/fixtures/80x60.png +0 -0
  178. data/spec/fixtures/animated.gif +0 -0
  179. data/spec/fixtures/image with spaces.png +0 -0
  180. data/spec/fixtures/image.png +0 -0
  181. data/spec/fixtures/image2.PNG +0 -0
  182. data/spec/fixtures/image3.jpeg +0 -0
  183. data/spec/helpers/alchemy/admin/attachments_helper_spec.rb +0 -15
  184. data/spec/helpers/alchemy/admin/base_helper_spec.rb +0 -280
  185. data/spec/helpers/alchemy/admin/contents_helper_spec.rb +0 -46
  186. data/spec/helpers/alchemy/admin/elements_helper_spec.rb +0 -314
  187. data/spec/helpers/alchemy/admin/essences_helper_spec.rb +0 -201
  188. data/spec/helpers/alchemy/admin/navigation_helper_spec.rb +0 -294
  189. data/spec/helpers/alchemy/admin/pages_helper_spec.rb +0 -63
  190. data/spec/helpers/alchemy/admin/pictures_helper_spec.rb +0 -28
  191. data/spec/helpers/alchemy/admin/tags_helper_spec.rb +0 -111
  192. data/spec/helpers/alchemy/base_helper_spec.rb +0 -44
  193. data/spec/helpers/alchemy/elements_block_helper_spec.rb +0 -135
  194. data/spec/helpers/alchemy/elements_helper_spec.rb +0 -326
  195. data/spec/helpers/alchemy/essences_helper_spec.rb +0 -85
  196. data/spec/helpers/alchemy/pages_helper_spec.rb +0 -499
  197. data/spec/helpers/alchemy/picture_url_helpers_spec.rb +0 -78
  198. data/spec/helpers/alchemy/url_helper_spec.rb +0 -200
  199. data/spec/javascripts/alchemy/dialog_spec.coffee +0 -82
  200. data/spec/javascripts/alchemy/link_overlay_spec.coffee +0 -25
  201. data/spec/javascripts/alchemy_integration_spec.coffee +0 -3
  202. data/spec/javascripts/fixtures/select.html +0 -3
  203. data/spec/javascripts/helpers/mock-ajax.js +0 -199
  204. data/spec/javascripts/helpers/test_responses/test_responses.js +0 -1
  205. data/spec/javascripts/support/jasmine.yml +0 -29
  206. data/spec/libraries/auth_accessors_spec.rb +0 -40
  207. data/spec/libraries/config_spec.rb +0 -111
  208. data/spec/libraries/controller_actions_spec.rb +0 -133
  209. data/spec/libraries/i18n_spec.rb +0 -37
  210. data/spec/libraries/kaminari/scoped_pagination_url_helper_spec.rb +0 -30
  211. data/spec/libraries/modules_spec.rb +0 -67
  212. data/spec/libraries/mount_point_spec.rb +0 -77
  213. data/spec/libraries/page_layout_spec.rb +0 -150
  214. data/spec/libraries/paths_spec.rb +0 -15
  215. data/spec/libraries/permissions_spec.rb +0 -260
  216. data/spec/libraries/resource_spec.rb +0 -344
  217. data/spec/libraries/resources_helper_spec.rb +0 -193
  218. data/spec/libraries/shell_spec.rb +0 -121
  219. data/spec/libraries/template_tracker_spec.rb +0 -85
  220. data/spec/libraries/tinymce_spec.rb +0 -111
  221. data/spec/libraries/userstamp_spec.rb +0 -10
  222. data/spec/mailers/alchemy/messages_spec.rb +0 -21
  223. data/spec/models/alchemy/attachment_spec.rb +0 -250
  224. data/spec/models/alchemy/cell_spec.rb +0 -101
  225. data/spec/models/alchemy/content_spec.rb +0 -513
  226. data/spec/models/alchemy/element_spec.rb +0 -862
  227. data/spec/models/alchemy/element_to_page_spec.rb +0 -13
  228. data/spec/models/alchemy/essence_boolean_spec.rb +0 -10
  229. data/spec/models/alchemy/essence_date_spec.rb +0 -28
  230. data/spec/models/alchemy/essence_file_spec.rb +0 -40
  231. data/spec/models/alchemy/essence_html_spec.rb +0 -18
  232. data/spec/models/alchemy/essence_link_spec.rb +0 -10
  233. data/spec/models/alchemy/essence_picture_spec.rb +0 -255
  234. data/spec/models/alchemy/essence_richtext_spec.rb +0 -23
  235. data/spec/models/alchemy/essence_select_spec.rb +0 -10
  236. data/spec/models/alchemy/essence_text_spec.rb +0 -110
  237. data/spec/models/alchemy/language_spec.rb +0 -243
  238. data/spec/models/alchemy/legacy_page_url_spec.rb +0 -21
  239. data/spec/models/alchemy/message_spec.rb +0 -55
  240. data/spec/models/alchemy/page_spec.rb +0 -2108
  241. data/spec/models/alchemy/picture_spec.rb +0 -418
  242. data/spec/models/alchemy/site_spec.rb +0 -168
  243. data/spec/models/alchemy/tag_spec.rb +0 -29
  244. data/spec/models/dummy_model_spec.rb +0 -10
  245. data/spec/requests/alchemy/admin/resources_requests_spec.rb +0 -26
  246. data/spec/requests/alchemy/admin/site_requests_spec.rb +0 -19
  247. data/spec/requests/alchemy/site_requests_spec.rb +0 -18
  248. data/spec/requests/alchemy/sitemap_spec.rb +0 -56
  249. data/spec/routing/api_routing_spec.rb +0 -150
  250. data/spec/routing/routing_spec.rb +0 -340
  251. data/spec/spec_helper.rb +0 -90
  252. data/spec/support/ci/install_phantomjs +0 -7
  253. data/spec/support/hint_examples.rb +0 -28
  254. data/spec/support/test_tweaks.rb +0 -31
  255. data/spec/support/transformation_examples.rb +0 -179
  256. data/spec/tasks/helpers_spec.rb +0 -217
  257. data/spec/views/admin/pictures/show_spec.rb +0 -43
  258. data/spec/views/essences/essence_boolean_editor_spec.rb +0 -32
  259. data/spec/views/essences/essence_boolean_view_spec.rb +0 -23
  260. data/spec/views/essences/essence_date_view_spec.rb +0 -38
  261. data/spec/views/essences/essence_file_editor_spec.rb +0 -59
  262. data/spec/views/essences/essence_file_view_spec.rb +0 -77
  263. data/spec/views/essences/essence_html_view_spec.rb +0 -22
  264. data/spec/views/essences/essence_link_view_spec.rb +0 -41
  265. data/spec/views/essences/essence_picture_editor_spec.rb +0 -80
  266. data/spec/views/essences/essence_picture_view_spec.rb +0 -128
  267. data/spec/views/essences/essence_richtext_view_spec.rb +0 -32
  268. data/spec/views/essences/essence_select_view_spec.rb +0 -11
  269. 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