alchemy_cms 3.2.0.beta → 3.2.0.rc1

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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +661 -863
  3. data/README.md +5 -63
  4. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +11 -10
  5. data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +6 -0
  6. data/app/assets/stylesheets/alchemy/_extends.scss +0 -6
  7. data/app/assets/stylesheets/alchemy/_mixins.scss +6 -0
  8. data/app/assets/stylesheets/alchemy/buttons.scss +1 -1
  9. data/app/assets/stylesheets/alchemy/elements.scss +1 -1
  10. data/app/assets/stylesheets/alchemy/menubar.scss +1 -1
  11. data/app/assets/stylesheets/alchemy/selects.scss +5 -1
  12. data/app/assets/stylesheets/alchemy/upload.scss +1 -1
  13. data/app/controllers/alchemy/admin/pages_controller.rb +1 -1
  14. data/app/controllers/alchemy/base_controller.rb +4 -57
  15. data/app/controllers/alchemy/messages_controller.rb +2 -2
  16. data/app/controllers/alchemy/pages_controller.rb +22 -31
  17. data/app/controllers/alchemy/pictures_controller.rb +2 -2
  18. data/app/helpers/alchemy/admin/base_helper.rb +7 -0
  19. data/app/helpers/alchemy/admin/elements_helper.rb +31 -15
  20. data/app/helpers/alchemy/admin/pages_helper.rb +17 -0
  21. data/app/helpers/alchemy/base_helper.rb +0 -28
  22. data/app/helpers/alchemy/pages_helper.rb +18 -12
  23. data/app/helpers/alchemy/url_helper.rb +2 -2
  24. data/app/models/alchemy/cell.rb +1 -1
  25. data/app/models/alchemy/content/factory.rb +12 -6
  26. data/app/models/alchemy/element.rb +3 -3
  27. data/app/models/alchemy/element/definitions.rb +1 -1
  28. data/app/models/alchemy/element_to_page.rb +7 -0
  29. data/app/models/alchemy/language.rb +1 -1
  30. data/app/models/alchemy/page.rb +8 -1
  31. data/app/models/alchemy/page/page_cells.rb +2 -2
  32. data/app/models/alchemy/page/page_elements.rb +23 -5
  33. data/app/models/alchemy/page/page_natures.rb +3 -3
  34. data/app/models/alchemy/page/page_scopes.rb +1 -1
  35. data/app/models/alchemy/picture.rb +1 -1
  36. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +1 -1
  37. data/app/views/alchemy/admin/pages/_form.html.erb +1 -1
  38. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -1
  39. data/app/views/alchemy/breadcrumb/_page.html.erb +3 -2
  40. data/app/views/alchemy/breadcrumb/_separator.html.erb +1 -0
  41. data/app/views/alchemy/breadcrumb/_wrapper.html.erb +13 -0
  42. data/app/views/alchemy/language_links/_language.html.erb +1 -1
  43. data/app/views/alchemy/navigation/_link.html.erb +1 -1
  44. data/app/views/alchemy/pages/show.rss.builder +5 -7
  45. data/app/views/layouts/alchemy/admin.html.erb +5 -0
  46. data/config/routes.rb +13 -10
  47. data/lib/alchemy/configuration_methods.rb +29 -0
  48. data/lib/alchemy/controller_actions.rb +12 -4
  49. data/lib/alchemy/engine.rb +3 -0
  50. data/lib/alchemy/errors.rb +1 -1
  51. data/lib/alchemy/essence.rb +14 -12
  52. data/lib/alchemy/on_page_layout.rb +58 -0
  53. data/lib/alchemy/page_layout.rb +1 -1
  54. data/lib/alchemy/permissions.rb +21 -16
  55. data/lib/alchemy/routing_constraints.rb +49 -0
  56. data/lib/alchemy/seeder.rb +4 -2
  57. data/lib/alchemy/ssl_protection.rb +30 -0
  58. data/lib/alchemy/test_support/essence_shared_examples.rb +118 -25
  59. data/lib/alchemy/test_support/factories.rb +5 -8
  60. data/lib/alchemy/test_support/integration_helpers.rb +16 -10
  61. data/lib/alchemy/upgrader/three_point_two.rb +34 -4
  62. data/lib/alchemy/version.rb +1 -1
  63. data/lib/rails/generators/alchemy/{scaffold → install}/files/_article_editor.html.erb +0 -0
  64. data/lib/rails/generators/alchemy/{scaffold → install}/files/_article_view.html.erb +0 -0
  65. data/lib/rails/generators/alchemy/{scaffold → install}/files/_standard.html.erb +0 -0
  66. data/lib/rails/generators/alchemy/{scaffold → install}/files/alchemy.de.yml +0 -0
  67. data/lib/rails/generators/alchemy/{scaffold → install}/files/alchemy.elements.css.scss +0 -0
  68. data/lib/rails/generators/alchemy/{scaffold → install}/files/alchemy.en.yml +0 -0
  69. data/lib/rails/generators/alchemy/{scaffold → install}/files/alchemy.es.yml +0 -0
  70. data/lib/rails/generators/alchemy/{scaffold → install}/files/application.html.erb +0 -0
  71. data/lib/rails/generators/alchemy/install/install_generator.rb +69 -0
  72. data/lib/rails/generators/alchemy/{scaffold/files/elements.yml → install/templates/elements.yml.tt} +2 -0
  73. data/lib/rails/generators/alchemy/{scaffold → install}/templates/page_layouts.yml.tt +2 -0
  74. data/lib/rails/generators/alchemy/views/views_generator.rb +41 -0
  75. data/lib/rails/templates/alchemy.rb +2 -2
  76. data/lib/tasks/alchemy/db.rake +0 -5
  77. data/lib/tasks/alchemy/install.rake +10 -5
  78. data/lib/tasks/alchemy/tidy.rake +2 -0
  79. data/spec/controllers/admin/attachments_controller_spec.rb +1 -1
  80. data/spec/controllers/admin/clipboard_controller_spec.rb +1 -1
  81. data/spec/controllers/admin/contents_controller_spec.rb +1 -1
  82. data/spec/controllers/admin/dashboard_controller_spec.rb +2 -2
  83. data/spec/controllers/admin/elements_controller_spec.rb +1 -1
  84. data/spec/controllers/admin/essence_files_controller_spec.rb +1 -1
  85. data/spec/controllers/admin/essence_pictures_controller_spec.rb +1 -1
  86. data/spec/controllers/admin/languages_controller_spec.rb +1 -1
  87. data/spec/controllers/admin/layoutpages_controller_spec.rb +1 -1
  88. data/spec/controllers/admin/pages_controller_spec.rb +4 -4
  89. data/spec/controllers/admin/pictures_controller_spec.rb +1 -1
  90. data/spec/controllers/admin/resources_controller_spec.rb +1 -1
  91. data/spec/controllers/admin/trash_controller_spec.rb +1 -1
  92. data/spec/controllers/alchemy/admin/tags_controller_spec.rb +1 -1
  93. data/spec/controllers/attachments_controller_spec.rb +1 -1
  94. data/spec/controllers/base_controller_spec.rb +22 -0
  95. data/spec/controllers/elements_controller_spec.rb +1 -1
  96. data/spec/controllers/pages_controller_spec.rb +15 -16
  97. data/spec/controllers/pictures_controller_spec.rb +212 -162
  98. data/spec/dummy/app/controllers/login_controller.rb +5 -0
  99. data/spec/dummy/app/models/dummy_model.rb +3 -0
  100. data/spec/dummy/config/alchemy/cells.yml +4 -1
  101. data/spec/dummy/config/alchemy/elements.yml +8 -0
  102. data/spec/dummy/config/alchemy/page_layouts.yml +5 -1
  103. data/spec/dummy/config/routes.rb +1 -2
  104. data/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb +7 -0
  105. data/spec/dummy/db/schema.rb +30 -26
  106. data/spec/features/admin/dashboard_spec.rb +11 -9
  107. data/spec/features/admin/language_tree_feature_spec.rb +5 -6
  108. data/spec/features/admin/legacy_page_url_management_spec.rb +1 -1
  109. data/spec/features/admin/link_overlay_spec.rb +1 -1
  110. data/spec/features/admin/locale_select_feature_spec.rb +1 -1
  111. data/spec/features/admin/modules_integration_spec.rb +1 -1
  112. data/spec/features/admin/navigation_feature_spec.rb +1 -1
  113. data/spec/features/admin/page_creation_feature_spec.rb +1 -1
  114. data/spec/features/admin/page_editing_feature_spec.rb +3 -3
  115. data/spec/features/admin/picture_library_integration_spec.rb +1 -1
  116. data/spec/features/admin/resources_integration_spec.rb +1 -1
  117. data/spec/features/admin/site_select_feature_spec.rb +32 -0
  118. data/spec/features/admin/tinymce_feature_spec.rb +1 -3
  119. data/spec/features/page_feature_spec.rb +36 -27
  120. data/spec/features/security_spec.rb +1 -1
  121. data/spec/features/translation_integration_spec.rb +3 -3
  122. data/spec/helpers/admin/elements_helper_spec.rb +103 -26
  123. data/spec/helpers/admin/pages_helper_spec.rb +32 -1
  124. data/spec/helpers/base_helper_spec.rb +0 -45
  125. data/spec/helpers/pages_helper_spec.rb +18 -17
  126. data/spec/helpers/url_helper_spec.rb +8 -5
  127. data/spec/libraries/controller_actions_spec.rb +2 -2
  128. data/spec/libraries/on_page_layout_spec.rb +112 -0
  129. data/spec/libraries/page_layout_spec.rb +5 -1
  130. data/spec/libraries/permissions_spec.rb +13 -15
  131. data/spec/models/cell_spec.rb +4 -0
  132. data/spec/models/content_spec.rb +6 -0
  133. data/spec/models/dummy_model_spec.rb +11 -0
  134. data/spec/models/element_spec.rb +6 -1
  135. data/spec/models/element_to_page_spec.rb +14 -0
  136. data/spec/models/page_spec.rb +111 -19
  137. data/spec/routing/routing_spec.rb +120 -101
  138. data/spec/spec_helper.rb +3 -3
  139. metadata +36 -21
  140. data/app/views/alchemy/breadcrumb/_spacer.html.erb +0 -1
  141. data/lib/alchemy/capistrano.rb +0 -230
  142. data/lib/alchemy/test_support/auth_helpers.rb +0 -35
  143. data/lib/rails/generators/alchemy/deploy_script/deploy_script_generator.rb +0 -90
  144. data/lib/rails/generators/alchemy/deploy_script/templates/deploy.rb.tt +0 -113
  145. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +0 -63
  146. data/spec/dummy/app/controllers/errors_controller.rb +0 -5
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  RSpec.feature "Picture Library" do
4
4
  before do
5
- authorize_as_admin
5
+ authorize_user(:as_admin)
6
6
  end
7
7
 
8
8
  describe "Tagging" do
@@ -4,7 +4,7 @@ describe "Resources" do
4
4
  let(:event) { FactoryGirl.create(:event) }
5
5
  let(:second_event) { FactoryGirl.create(:event, :name => 'My second Event', :entrance_fee => 12.32) }
6
6
 
7
- before { authorize_as_admin }
7
+ before { authorize_user(:as_admin) }
8
8
 
9
9
  describe "index view" do
10
10
 
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Site select' do
4
+
5
+ before do
6
+ authorize_user(:as_admin)
7
+ end
8
+
9
+ it "does not display the site change" do
10
+ visit admin_dashboard_path
11
+ expect(page).not_to have_select('change_site')
12
+ end
13
+
14
+ context "multiple sites" do
15
+ let!(:a_site) { FactoryGirl.create(:site) }
16
+
17
+ it "contains all sites in a selectbox" do
18
+ visit admin_dashboard_path
19
+ expect(page).to have_select('change_site', options: [Alchemy::Site.default.name, a_site.name], selected: Alchemy::Site.default.name)
20
+ end
21
+
22
+ context 'when requesting non-default site' do
23
+ it "provides the correct site" do
24
+ visit admin_pages_path(site_id: a_site.id)
25
+ expect(page).to have_select('change_site', selected: a_site.name)
26
+
27
+ visit admin_dashboard_path
28
+ expect(page).to have_select('change_site', selected: a_site.name)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,11 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'TinyMCE Editor' do
4
- let(:user) { DummyUser.new }
5
4
 
6
5
  before do
7
- user.update(alchemy_roles: %w(admin), name: "Joe User", id: 1)
8
- authorize_as_admin(user)
6
+ authorize_user(:as_admin)
9
7
  end
10
8
 
11
9
  it 'base path should be set to tinymce asset folder' do
@@ -3,14 +3,14 @@ require 'spec_helper'
3
3
  module Alchemy
4
4
  describe 'Page' do
5
5
  let(:default_language) { Language.default }
6
- let(:default_language_root) { FactoryGirl.create(:language_root_page, :language => default_language, :name => 'Home') }
7
- let(:public_page_1) { FactoryGirl.create(:public_page, :visible => true, :name => 'Page 1') }
8
- let(:public_child) { FactoryGirl.create(:public_page, :name => 'Public Child', :parent_id => public_page_1.id) }
6
+ let(:default_language_root) { create(:language_root_page, :language => default_language, :name => 'Home') }
7
+ let(:public_page_1) { create(:public_page, :visible => true, :name => 'Page 1') }
8
+ let(:public_child) { create(:public_page, :name => 'Public Child', :parent_id => public_page_1.id) }
9
9
 
10
10
  before { default_language_root }
11
11
 
12
12
  it "should include all its elements and contents" do
13
- p = FactoryGirl.create(:public_page, :do_not_autogenerate => false)
13
+ p = create(:public_page, :do_not_autogenerate => false)
14
14
  article = p.elements.find_by_name('article')
15
15
  article.content_by_name('intro').essence.update_attributes(:body => 'Welcome to Peters Petshop', :public => true)
16
16
  visit "/#{p.urlname}"
@@ -19,8 +19,8 @@ module Alchemy
19
19
 
20
20
  it "should show the navigation with all visible pages" do
21
21
  pages = [
22
- FactoryGirl.create(:public_page, :visible => true, :name => 'Page 1'),
23
- FactoryGirl.create(:public_page, :visible => true, :name => 'Page 2')
22
+ create(:public_page, :visible => true, :name => 'Page 1'),
23
+ create(:public_page, :visible => true, :name => 'Page 2')
24
24
  ]
25
25
  visit '/'
26
26
  within('div#navigation ul') { expect(page).to have_selector('li a[href="/page-1"], li a[href="/page-2"]') }
@@ -33,7 +33,7 @@ module Alchemy
33
33
  allow_any_instance_of(PagesController).to receive(:multi_language?).and_return(true)
34
34
  end
35
35
 
36
- let(:second_page) { FactoryGirl.create(:public_page, name: 'Second Page') }
36
+ let(:second_page) { create(:public_page, name: 'Second Page') }
37
37
  let(:legacy_url) { LegacyPageUrl.create(urlname: 'index.php?option=com_content&view=article&id=48&Itemid=69', page: second_page) }
38
38
 
39
39
  it "should redirect legacy url with unknown format & query string" do
@@ -100,16 +100,18 @@ module Alchemy
100
100
  before { allow(Alchemy.user_class).to receive(:admins).and_return([1, 2]) }
101
101
 
102
102
  it "should render 404 if urlname and lang parameter do not belong to same page" do
103
- FactoryGirl.create(:klingonian)
104
- visit "/kl/#{public_page_1.urlname}"
105
- expect(page.status_code).to eq(404)
103
+ create(:klingonian)
104
+ expect {
105
+ visit "/kl/#{public_page_1.urlname}"
106
+ }.to raise_error(ActionController::RoutingError)
106
107
  end
107
108
 
108
109
  it "should render 404 if requested language does not exist" do
109
110
  public_page_1
110
111
  LegacyPageUrl.delete_all
111
- visit "/fo/#{public_page_1.urlname}"
112
- expect(page.status_code).to eq(404)
112
+ expect {
113
+ visit "/fo/#{public_page_1.urlname}"
114
+ }.to raise_error(ActionController::RoutingError)
113
115
  end
114
116
  end
115
117
  end
@@ -120,7 +122,7 @@ module Alchemy
120
122
  allow(Config).to receive(:get) { |arg| arg == :url_nesting ? false : Config.parameter(arg) }
121
123
  end
122
124
 
123
- let(:second_page) { FactoryGirl.create(:public_page, name: 'Second Page') }
125
+ let(:second_page) { create(:public_page, name: 'Second Page') }
124
126
  let(:legacy_url) { LegacyPageUrl.create(urlname: 'index.php?option=com_content&view=article&id=48&Itemid=69', page: second_page) }
125
127
 
126
128
  it "should redirect legacy url with unknown format & query string" do
@@ -158,7 +160,7 @@ module Alchemy
158
160
  end
159
161
 
160
162
  it "should keep additional params" do
161
- visit "/de/#{public_page_1.urlname}?query=Peter"
163
+ visit "/en/#{public_page_1.urlname}?query=Peter"
162
164
  expect(page.current_url).to match(/\?query=Peter/)
163
165
  end
164
166
  end
@@ -166,12 +168,14 @@ module Alchemy
166
168
 
167
169
  describe "Handling of non-existing pages" do
168
170
  before do
169
- allow(Alchemy.user_class).to receive(:admins).and_return([1, 2]) # We need a admin user or the signup page will show up
170
- visit "/non-existing-page"
171
+ # We need a admin user or the signup page will show up
172
+ allow(Alchemy.user_class).to receive(:admins).and_return([1, 2])
171
173
  end
172
174
 
173
175
  it "should render public/404.html" do
174
- expect(page.status_code).to eq(404)
176
+ expect {
177
+ visit "/non-existing-page"
178
+ }.to raise_error(ActionController::RoutingError)
175
179
  end
176
180
  end
177
181
 
@@ -191,7 +195,7 @@ module Alchemy
191
195
 
192
196
  context "rendering for members" do
193
197
  it "is prohibited" do
194
- authorize_as_admin(mock_model('DummyUser', alchemy_roles: %w(member), language: 'en'))
198
+ authorize_user(build(:alchemy_dummy_user))
195
199
  visit "/#{public_page_1.urlname}"
196
200
  within('body') { expect(page).not_to have_selector('#alchemy_menubar') }
197
201
  end
@@ -199,7 +203,7 @@ module Alchemy
199
203
 
200
204
  context "rendering for authors" do
201
205
  it "is allowed" do
202
- authorize_as_admin(mock_model('DummyUser', alchemy_roles: %w(author), language: 'en', cache_key: 'aaa'))
206
+ authorize_user(:as_author)
203
207
  visit "/#{public_page_1.urlname}"
204
208
  within('body') { expect(page).to have_selector('#alchemy_menubar') }
205
209
  end
@@ -207,7 +211,7 @@ module Alchemy
207
211
 
208
212
  context "rendering for editors" do
209
213
  it "is allowed" do
210
- authorize_as_admin(mock_model('DummyUser', alchemy_roles: %w(editor), language: 'en', cache_key: 'aaa'))
214
+ authorize_user(:as_editor)
211
215
  visit "/#{public_page_1.urlname}"
212
216
  within('body') { expect(page).to have_selector('#alchemy_menubar') }
213
217
  end
@@ -215,7 +219,7 @@ module Alchemy
215
219
 
216
220
  context "rendering for admins" do
217
221
  it "is allowed" do
218
- authorize_as_admin(mock_model('DummyUser', alchemy_roles: %w(admin), language: 'en', cache_key: 'aaa'))
222
+ authorize_user(:as_admin)
219
223
  visit "/#{public_page_1.urlname}"
220
224
  within('body') { expect(page).to have_selector('#alchemy_menubar') }
221
225
  end
@@ -223,20 +227,26 @@ module Alchemy
223
227
 
224
228
  context "contains" do
225
229
  before do
226
- authorize_as_admin(mock_model('DummyUser', alchemy_roles: %w(admin), language: 'en', cache_key: 'aaa'))
230
+ authorize_user(:as_admin)
227
231
  visit "/#{public_page_1.urlname}"
228
232
  end
229
233
 
230
234
  it "a link to the admin area" do
231
- within('#alchemy_menubar') { expect(page).to have_selector("li a[href='#{alchemy.admin_dashboard_path}']") }
235
+ within('#alchemy_menubar') do
236
+ expect(page).to have_selector("li a[href='#{alchemy.admin_dashboard_path}']")
237
+ end
232
238
  end
233
239
 
234
240
  it "a link to edit the current page" do
235
- within('#alchemy_menubar') { expect(page).to have_selector("li a[href='#{alchemy.edit_admin_page_path(public_page_1)}']") }
241
+ within('#alchemy_menubar') do
242
+ expect(page).to have_selector("li a[href='#{alchemy.edit_admin_page_path(public_page_1)}']")
243
+ end
236
244
  end
237
245
 
238
246
  it "a form and button to logout of alchemy" do
239
- within('#alchemy_menubar') { expect(page).to have_selector("li form[action='#{Alchemy.logout_path}'], li button[type='submit']") }
247
+ within('#alchemy_menubar') do
248
+ expect(page).to have_selector("li form[action='#{Alchemy.logout_path}'], li button[type='submit']")
249
+ end
240
250
  end
241
251
  end
242
252
  end
@@ -265,7 +275,7 @@ module Alchemy
265
275
  end
266
276
 
267
277
  context 'as a member user' do
268
- before { authorize_as_admin(create(:member_user)) }
278
+ before { authorize_user(create(:alchemy_dummy_user)) }
269
279
 
270
280
  it "I am able to visit the page" do
271
281
  visit restricted_page.urlname
@@ -273,6 +283,5 @@ module Alchemy
273
283
  end
274
284
  end
275
285
  end
276
-
277
286
  end
278
287
  end
@@ -13,7 +13,7 @@ describe "Security." do
13
13
  allow_any_instance_of(Alchemy::BaseController)
14
14
  .to receive(:ssl_required?)
15
15
  .and_return(true)
16
- authorize_as_admin(DummyUser.new(alchemy_roles: %w(admin)))
16
+ authorize_user(:as_admin)
17
17
  end
18
18
 
19
19
  it "redirects every request to https." do
@@ -2,9 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe "Translation integration" do
4
4
  context "in admin backend" do
5
- let(:dummy_user) { mock_model('DummyUser', alchemy_roles: %w(admin), language: 'de') }
5
+ let(:dummy_user) { mock_model(Alchemy.user_class, alchemy_roles: %w(admin), language: 'de') }
6
6
 
7
- before { authorize_as_admin(dummy_user) }
7
+ before { authorize_user(dummy_user) }
8
8
 
9
9
  it "should be possible to set the locale of the admin backend via params" do
10
10
  visit admin_dashboard_path(locale: 'nl')
@@ -38,7 +38,7 @@ describe "Translation integration" do
38
38
  end
39
39
 
40
40
  context "if user has no preferred locale" do
41
- let(:dummy_user) { mock_model('DummyUser', alchemy_roles: %w(admin), language: nil) }
41
+ let(:dummy_user) { mock_model(Alchemy.user_class, alchemy_roles: %w(admin), language: nil) }
42
42
 
43
43
  it "should use the browsers language setting" do
44
44
  page.driver.header 'ACCEPT-LANGUAGE', 'es-ES'
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe Admin::ElementsHelper do
5
-
6
5
  let(:page) { build_stubbed(:public_page) }
7
6
  let(:element) { build_stubbed(:element, page: page) }
8
7
 
@@ -18,46 +17,124 @@ module Alchemy
18
17
  end
19
18
 
20
19
  describe "#grouped_elements_for_select" do
21
- let(:elements) {
20
+ let(:elements) do
22
21
  [
23
22
  mock_model('Element', name: '1', display_name: '1'),
24
23
  mock_model('Element', name: '2', display_name: '2')
25
24
  ]
26
- }
25
+ end
26
+ let(:element_definitions) { [{"name" => "1"}, {"name" => "2"}] }
27
+ let(:cell_definitions) { [] }
28
+ let(:page_definition) { {} }
27
29
 
28
30
  before do
29
- allow(page).to receive(:layout_description).and_return({
30
- 'name' => "foo",
31
- 'cells' => ["foo_cell"]
32
- })
33
- cell_descriptions = [{
34
- 'name' => "foo_cell",
35
- 'elements' => ["1", "2"]
36
- }]
37
- allow(Cell).to receive(:definitions).and_return(cell_descriptions)
31
+ allow(page).to receive(:definition).and_return(page_definition)
32
+ allow(Cell).to receive(:definitions).and_return(cell_definitions)
33
+ allow(Element).to receive(:definitions).and_return(element_definitions)
38
34
  helper.instance_variable_set('@page', page)
39
35
  end
40
36
 
41
- it "should return array of elements grouped by cell for select_tag helper" do
42
- expect(helper.grouped_elements_for_select(elements)).to include("Foo cell" => [["1", "1#foo_cell"], ["2", "2#foo_cell"]])
37
+ context "with empty elements array given" do
38
+ it "return an empty array" do
39
+ expect(helper.grouped_elements_for_select([])).to eq([])
40
+ end
43
41
  end
44
42
 
45
- context "with empty elements array" do
46
- it "should return an empty string" do
47
- expect(helper.grouped_elements_for_select([])).to eq("")
43
+ context "with an element collection given" do
44
+ let(:page_definition) do
45
+ {'name' => "foo", 'cells' => ["foo_cell"], 'elements' => []}
48
46
  end
49
- end
50
47
 
51
- context "with empty cell definitions" do
52
- it "should return an empty string" do
53
- allow(page).to receive(:layout_description).and_return({'name' => "foo"})
54
- expect(helper.grouped_elements_for_select(elements)).to eq("")
48
+ let(:cell_definitions) do
49
+ [{'name' => "foo_cell", 'elements' => ["1", "2"]}]
50
+ end
51
+
52
+ it "returns an array of elements grouped by cell for select_tag helper" do
53
+ expect(helper.grouped_elements_for_select(elements)).to eq("Foo cell" => [["1", "1#foo_cell"], ["2", "2#foo_cell"]])
54
+ end
55
+
56
+ context "without cells key in page definition" do
57
+ let(:page_definition) do
58
+ {'name' => "foo", "elements" => ["1", "2"]}
59
+ end
60
+
61
+ it "returns an empty array" do
62
+ expect(helper.grouped_elements_for_select(elements)).to eq([])
63
+ end
64
+ end
65
+
66
+ context "with empty cells in page definition" do
67
+ let(:page_definition) do
68
+ {"name" => "foo", "cells" => [], "elements" => ["1", "2"]}
69
+ end
70
+
71
+ it "returns an empty array" do
72
+ expect(helper.grouped_elements_for_select(elements)).to eq([])
73
+ end
74
+ end
75
+
76
+ context "with a cell containing no elements" do
77
+ let(:cell_definitions) do
78
+ [{"name" => "empty_cell", "elements" => []}]
79
+ end
80
+
81
+ let(:page_definition) do
82
+ {"name" => "foo", "cells" => ["empty_cell"], "elements" => ["1", "2"]}
83
+ end
84
+
85
+ it "does not include that cell" do
86
+ expect(helper.grouped_elements_for_select(elements)).to eq("Main content" => [["1", "1"], ["2", "2"]])
87
+ end
88
+ end
89
+
90
+ context "with an element in a cell only" do
91
+ let(:elements) do
92
+ [mock_model('Element', name: 'in_cell', display_name: 'In Cell')]
93
+ end
94
+
95
+ let(:page_definition) do
96
+ {'name' => "foo", 'cells' => ["foo_cell"], 'elements' => []}
97
+ end
98
+
99
+ let(:cell_definitions) do
100
+ [{'name' => "foo_cell", 'elements' => ["in_cell"]}]
101
+ end
102
+
103
+ it "returns an option for the element in the cell only" do
104
+ expect(helper.grouped_elements_for_select(elements)).to include("Foo cell" => [["In cell", "in_cell#foo_cell"]])
105
+ end
55
106
  end
56
- end
57
107
 
58
- context "with cell having no elements" do
59
- it "should remove that cell from hash" do
60
- expect(helper.grouped_elements_for_select(elements)['Empty cell']).to be_nil
108
+ context "with the same element in both cell and page" do
109
+ let(:element_definitions) do
110
+ [{"name" => "in_cell_and_page"}]
111
+ end
112
+
113
+ let(:elements) do
114
+ [mock_model('Element', name: 'in_cell_and_page', display_name: 'In Cell and Page')]
115
+ end
116
+
117
+ let(:page_definition) do
118
+ {
119
+ 'name' => "foo",
120
+ 'cells' => ["foo_cell"],
121
+ 'elements' => ["in_cell_and_page"]
122
+ }
123
+ end
124
+
125
+ let(:cell_definitions) do
126
+ [{
127
+ 'name' => "foo_cell",
128
+ 'elements' => ["in_cell_and_page"]
129
+ }]
130
+ end
131
+
132
+ it "returns two options of same element, one for the cell and one for the page" do
133
+ expect(helper.grouped_elements_for_select(elements)).to eq({
134
+ "Main content" => [["In cell and page", "in_cell_and_page"]],
135
+ "Foo cell" => [["In cell and page", "in_cell_and_page#foo_cell"]]
136
+ })
137
+ end
61
138
  end
62
139
  end
63
140
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Alchemy::Admin::PagesHelper do
4
4
 
5
5
  describe '#sitemap_folder_link' do
6
- let(:user) { admin_user }
6
+ let(:user) { build(:alchemy_dummy_user, :as_admin) }
7
7
 
8
8
  before { allow(helper).to receive(:current_alchemy_user).and_return(user) }
9
9
 
@@ -61,4 +61,35 @@ describe Alchemy::Admin::PagesHelper do
61
61
  end
62
62
  end
63
63
 
64
+ describe '#page_layout_label' do
65
+ let(:page) { build(:page) }
66
+
67
+ subject { helper.page_layout_label(page) }
68
+
69
+ context 'when page is not yet persisted' do
70
+ it 'displays text only' do
71
+ is_expected.to eq(Alchemy::I18n.t(:page_type))
72
+ end
73
+ end
74
+
75
+ context 'when page is persited' do
76
+ before { page.save! }
77
+
78
+ context 'with page layout existing' do
79
+ it 'displays text only' do
80
+ is_expected.to eq(Alchemy::I18n.t(:page_type))
81
+ end
82
+ end
83
+
84
+ context 'with page layout description missing' do
85
+ before do
86
+ expect(page).to receive(:layout_description).and_return([])
87
+ end
88
+
89
+ it 'displays icon with warning' do
90
+ is_expected.to match /warning icon/
91
+ end
92
+ end
93
+ end
94
+ end
64
95
  end