alchemy_cms 2.6.0.rc5 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/.travis.yml +1 -1
  2. data/Gemfile +2 -1
  3. data/README.md +2 -4
  4. data/alchemy_cms.gemspec +1 -1
  5. data/app/assets/fonts/alchemy/icons.eot +0 -0
  6. data/app/assets/fonts/alchemy/icons.svg +71 -0
  7. data/app/assets/fonts/alchemy/icons.ttf +0 -0
  8. data/app/assets/fonts/alchemy/icons.woff +0 -0
  9. data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +6 -8
  10. data/app/assets/javascripts/alchemy/alchemy.hotkeys.js.coffee +2 -3
  11. data/app/assets/javascripts/alchemy/alchemy.image_cropper.js.coffee +3 -8
  12. data/app/assets/javascripts/alchemy/alchemy.link_overlay.js.coffee +3 -3
  13. data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +19 -9
  14. data/app/assets/javascripts/tiny_mce/plugins/alchemy_link/editor_plugin.js +6 -7
  15. data/app/assets/stylesheets/alchemy/admin.css.scss +0 -1
  16. data/app/assets/stylesheets/alchemy/archive.scss +55 -7
  17. data/app/assets/stylesheets/alchemy/base.scss +8 -144
  18. data/app/assets/stylesheets/alchemy/defaults.scss +1 -1
  19. data/app/assets/stylesheets/alchemy/elements.scss +20 -16
  20. data/app/assets/stylesheets/alchemy/flash.scss +1 -1
  21. data/app/assets/stylesheets/alchemy/form_elements.scss +49 -42
  22. data/app/assets/stylesheets/alchemy/icon-font.css.scss +67 -0
  23. data/app/assets/stylesheets/alchemy/icons.scss +16 -4
  24. data/app/assets/stylesheets/alchemy/jquery-ui.scss +40 -26
  25. data/app/assets/stylesheets/alchemy/menubar.css.scss +1 -1
  26. data/app/assets/stylesheets/alchemy/notices.scss +6 -1
  27. data/app/assets/stylesheets/alchemy/search.scss +3 -2
  28. data/app/assets/stylesheets/alchemy/sitemap.scss +72 -13
  29. data/app/assets/stylesheets/alchemy/tables.scss +31 -24
  30. data/app/assets/stylesheets/alchemy/upload.scss +1 -1
  31. data/app/assets/stylesheets/alchemy/variables.scss +2 -1
  32. data/app/assets/stylesheets/tiny_mce/plugins/inlinepopups/skins/{alchemy → alchemy-tinymce-dialog}/window.css.scss +70 -65
  33. data/app/controllers/alchemy/admin/base_controller.rb +7 -4
  34. data/app/controllers/alchemy/admin/pictures_controller.rb +2 -0
  35. data/app/controllers/alchemy/admin/users_controller.rb +1 -1
  36. data/app/controllers/alchemy/user_sessions_controller.rb +1 -1
  37. data/app/helpers/alchemy/admin/base_helper.rb +161 -60
  38. data/app/helpers/alchemy/admin/pages_helper.rb +4 -1
  39. data/app/helpers/alchemy/elements_block_helper.rb +1 -1
  40. data/app/helpers/alchemy/elements_helper.rb +119 -31
  41. data/app/helpers/alchemy/pages_helper.rb +29 -72
  42. data/app/models/alchemy/attachment.rb +0 -2
  43. data/app/models/alchemy/content.rb +1 -1
  44. data/app/models/alchemy/language.rb +1 -0
  45. data/app/models/alchemy/page.rb +8 -8
  46. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +3 -1
  47. data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
  48. data/app/views/alchemy/admin/attachments/_tag_list.html.erb +25 -27
  49. data/app/views/alchemy/admin/attachments/index.html.erb +4 -1
  50. data/app/views/alchemy/admin/elements/_elements_select.html.erb +6 -6
  51. data/app/views/alchemy/admin/elements/list.js.erb +1 -1
  52. data/app/views/alchemy/admin/pages/_page.html.erb +1 -1
  53. data/app/views/alchemy/admin/pages/_page_for_links.html.erb +1 -1
  54. data/app/views/alchemy/admin/pages/edit.html.erb +4 -2
  55. data/app/views/alchemy/admin/pictures/_archive.html.erb +0 -1
  56. data/app/views/alchemy/admin/pictures/_filter_bar.html.erb +2 -1
  57. data/app/views/alchemy/admin/pictures/_picture.html.erb +5 -0
  58. data/app/views/alchemy/admin/pictures/index.html.erb +1 -0
  59. data/app/views/alchemy/base/500.html.erb +26 -5
  60. data/app/views/alchemy/essences/_essence_picture_tools.html.erb +1 -1
  61. data/app/views/alchemy/essences/_linkable_essence_tools.html.erb +1 -1
  62. data/app/views/alchemy/language_links/_language.html.erb +12 -0
  63. data/app/views/alchemy/language_links/_spacer.html.erb +1 -0
  64. data/config/locales/alchemy.de.yml +7 -3
  65. data/config/locales/alchemy.en.yml +8 -3
  66. data/lib/alchemy/page_layout.rb +1 -1
  67. data/lib/alchemy/tinymce.rb +1 -1
  68. data/lib/alchemy/upgrader.rb +26 -0
  69. data/lib/alchemy/version.rb +1 -1
  70. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +4 -1
  71. data/lib/tasks/ferret.rake +1 -0
  72. data/spec/controllers/admin/users_controller_spec.rb +5 -5
  73. data/spec/features/admin/pages_controller_spec.rb +1 -1
  74. data/spec/helpers/admin/pages_helper_spec.rb +31 -0
  75. data/spec/helpers/pages_helper_spec.rb +60 -72
  76. data/spec/models/content_spec.rb +2 -1
  77. data/spec/models/page_layout_spec.rb +29 -0
  78. data/spec/models/page_spec.rb +33 -1
  79. data/spec/support/alchemy/test_tweaks.rb +2 -6
  80. metadata +34 -12
  81. data/app/assets/fonts/alchemy-icons.eot +0 -0
  82. data/app/assets/fonts/alchemy-icons.svg +0 -54
  83. data/app/assets/fonts/alchemy-icons.ttf +0 -0
  84. data/app/assets/fonts/alchemy-icons.woff +0 -0
  85. data/app/assets/images/alchemy/placeholder.png +0 -0
  86. data/app/assets/stylesheets/alchemy/fonts.scss +0 -46
@@ -0,0 +1 @@
1
+ <%= options[:spacer].html_safe %>
@@ -186,6 +186,7 @@ de:
186
186
  site:
187
187
  aliases: Weitere Domains bitte mit Leerzeichen oder Leerzeile getrennt angeben.
188
188
 
189
+ back: 'zurück'
189
190
  create_tree_as_new_language: "%{language} als neuen Sprachbaum anlegen"
190
191
  "<a href=\"http://get.adobe.com/flashplayer\" target=\"_blank\">%{value}</a>": ""
191
192
  "Active Pages": "Aktive Seiten"
@@ -193,6 +194,7 @@ de:
193
194
  "Adobe Website": "Adobe Webseite"
194
195
  "Alchemy is open software and itself uses open software and free resources:": "Alchemy ist offene Software und benutzt selbst offene Software und freie Ressourcen:"
195
196
  "Alchemy is up to date": 'Alchemy ist aktuell'
197
+ 'An error happened': 'Es ist leider ein Fehler aufgetreten!'
196
198
  "Change password": "Passwort ändern"
197
199
  "Choose page": "Seite wählen"
198
200
  "Cleared trash": "Der Papierkorb wurde geleert"
@@ -220,7 +222,7 @@ de:
220
222
  "File successfully updated": "Datei wurde erfolgreich gespeichert."
221
223
  "File upload error: %{error}": "Datei konnte nicht hochgeladen werden: %{error}"
222
224
  "File: '%{name}' deleted successfully": "%{name} wurde gelöscht"
223
- "Filter by tag": "Nach Tags filtern"
225
+ "Filter by tag": "Nach Tag filtern"
224
226
  "Flush page cache": "Seitencache löschen"
225
227
  "Flush picture cache": "Bildercache löschen"
226
228
  "Hide childpages": "Unterseiten ausblenden"
@@ -520,8 +522,9 @@ de:
520
522
  picture_gallery_editor: 'Bilder'
521
523
  picture_library:
522
524
  filter:
523
- last_upload: "Zuletzt hochgeladene Bilder"
524
- recent: "Bilder der letzten 24 Stunden"
525
+ last_upload: "die zuletzt hochgeladen wurden"
526
+ recent: "aus den letzten 24 Stunden"
527
+ without_tag: "ohne Tag"
525
528
  place_link: "Text verlinken"
526
529
  player_version: "Flashplayer Version"
527
530
  "please enter subject and mail address": "Bitte geben Sie den Betreff und eine Empfängeradresse an."
@@ -594,6 +597,7 @@ de:
594
597
  "We need at least one default.": "Es muss eine Standardsprache geben."
595
598
  welcome_please_identify_notice: "Willkommen! Bitte identifizieren Sie sich."
596
599
  width: "Breite"
600
+ without_tag: 'Ohne Tag'
597
601
  you_can_rename_this_tag: "Sie können dieses Tag umbenennen"
598
602
  zoom_image: "Bild in voller Größe anzeigen."
599
603
  "Leave Alchemy": "Alchemy verlassen"
@@ -333,7 +333,7 @@ en:
333
333
  "false": ""
334
334
  restricted:
335
335
  "true": "Page is restricted."
336
- "false": ""
336
+ "false": "Page is not restricted."
337
337
  page_status: "Status"
338
338
  page_title: "Title"
339
339
  page_type: "Type"
@@ -352,8 +352,9 @@ en:
352
352
  pictures_deleted_successfully: "Pictures %{name} deleted"
353
353
  picture_library:
354
354
  filter:
355
- last_upload: "Showing only pictures from last upload"
356
- recent: "Showing only recently uploaded pictures"
355
+ last_upload: "from last upload"
356
+ recent: "that where recently uploaded"
357
+ without_tag: "without tag"
357
358
  place_link: "Link text"
358
359
  player_version: "Flashplayer Version"
359
360
  "please enter subject and mail address": "Please enter recipient and subject."
@@ -611,6 +612,10 @@ en:
611
612
  one: File
612
613
  other: Files
613
614
 
615
+ alchemy/picture:
616
+ one: Picture
617
+ other: Pictures
618
+
614
619
  attributes:
615
620
 
616
621
  alchemy/attachment:
@@ -8,7 +8,7 @@ module Alchemy
8
8
  puts "\n+++ Warning: No Layout Description for #{page_layout} found! in page_layouts.yml\n"
9
9
  return []
10
10
  else
11
- layout_description["elements"]
11
+ layout_description["elements"] || []
12
12
  end
13
13
  end
14
14
 
@@ -20,7 +20,7 @@ module Alchemy
20
20
  :theme => 'advanced',
21
21
  :skin => 'o2k7',
22
22
  :skin_variant => 'silver',
23
- :inlinepopups_skin => 'alchemy',
23
+ :inlinepopups_skin => 'alchemy-tinymce-dialog',
24
24
  :popup_css => "/assets/alchemy/tinymce_dialog.css",
25
25
  :content_css => "/assets/alchemy/tinymce_content.css",
26
26
  :dialog_type => "modal",
@@ -20,11 +20,37 @@ module Alchemy
20
20
  Rake::Task['alchemy:install:migrations'].invoke
21
21
  Rake::Task['db:migrate'].invoke
22
22
  Seeder.seed!
23
+ convert_attachment_storage
23
24
  copy_new_config_file
24
25
  end
25
26
 
26
27
  private
27
28
 
29
+ def convert_attachment_storage
30
+ desc "Convert the attachment storage"
31
+ converted_files = []
32
+ files = Dir.glob Rails.root.join 'uploads/attachments/**/*.*'
33
+ if files.blank?
34
+ log "No attachments found", :skip
35
+ else
36
+ files.each do |file|
37
+ file_uid = file.gsub(/#{Rails.root.to_s}\/uploads\/attachments\//, '')
38
+ file_id = file_uid.split('/')[1].to_i
39
+ attachment = Alchemy::Attachment.find_by_id(file_id)
40
+ if attachment && attachment.file_uid.blank?
41
+ attachment.file_uid = file_uid
42
+ attachment.file_size = File.new(file).size
43
+ attachment.file_name = attachment.sanitized_filename
44
+ if attachment.save!
45
+ log "Converted #{file_uid}"
46
+ end
47
+ else
48
+ log "Attachment with id #{file_id} not found or already converted.", :skip
49
+ end
50
+ end
51
+ end
52
+ end
53
+
28
54
  def copy_new_config_file
29
55
  desc "Copy configuration file."
30
56
  config_file = Rails.root.join('config/alchemy/config.yml')
@@ -1,6 +1,6 @@
1
1
  module Alchemy
2
2
 
3
- VERSION = "2.6.0.rc5"
3
+ VERSION = "2.6.0"
4
4
 
5
5
  def self.version
6
6
  VERSION
@@ -3,6 +3,9 @@ require 'rails'
3
3
  module Alchemy
4
4
  module Generators
5
5
  class ScaffoldGenerator < ::Rails::Generators::Base
6
+
7
+ ALCHEMY_VIEWS = %w(breadcrumb language_links messages navigation notifications search)
8
+
6
9
  desc "This generator generates the Alchemy scaffold."
7
10
  class_option :copy_views, :default => false, :type => :boolean, :desc => "Copy all Alchemy views into your app.", :aliases => '-v'
8
11
  source_root File.expand_path('templates', File.dirname(__FILE__))
@@ -37,7 +40,7 @@ module Alchemy
37
40
  end
38
41
 
39
42
  def copy_alchemy_views
40
- %w(breadcrumb messages navigation notifications search).each do |dir|
43
+ ALCHEMY_VIEWS.each do |dir|
41
44
  src = File.expand_path("../../../../../app/views/alchemy/#{dir}", File.dirname(__FILE__))
42
45
  dest = Rails.root.join('app/views/alchemy', dir)
43
46
  directory src, dest
@@ -2,6 +2,7 @@ namespace :ferret do
2
2
 
3
3
  desc "Updates the Ferret index."
4
4
  task :rebuild_index => :environment do
5
+ abort 'Enable ferret search in Alchemy config first.' if !Alchemy::Config.get(:ferret)
5
6
  Alchemy::EssenceText.where(:do_not_index => false).rebuild_index
6
7
  Alchemy::EssenceRichtext.where(:do_not_index => false).rebuild_index
7
8
  end
@@ -49,17 +49,17 @@ describe Alchemy::Admin::UsersController do
49
49
 
50
50
  context "if user is permitted to update roles" do
51
51
  it "updates the user including role" do
52
- controller.stub(:permitted_to?).with(:update_role).and_return { true }
53
- Alchemy::User.any_instance.should_receive(:update_attributes).with({'role' => 'Administrator'})
54
- post :update, :id => user.id, :user => {:role => 'Administrator'}, :format => :js
52
+ controller.stub(:permitted_to?).with(:update_roles).and_return { true }
53
+ Alchemy::User.any_instance.should_receive(:update_attributes).with({'roles' => ['Administrator']})
54
+ post :update, :id => user.id, :user => {:roles => ['Administrator']}, :format => :js
55
55
  end
56
56
  end
57
57
 
58
58
  context "if the user is not permitted to update roles" do
59
59
  it "updates user without role" do
60
- controller.stub(:permitted_to?).with(:update_role).and_return { false }
60
+ controller.stub(:permitted_to?).with(:update_roles).and_return { false }
61
61
  Alchemy::User.any_instance.should_receive(:update_attributes).with({})
62
- post :update, :id => user.id, :user => {'role' => 'Administrator'}, :format => :js
62
+ post :update, :id => user.id, :user => {'roles' => ['Administrator']}, :format => :js
63
63
  end
64
64
  end
65
65
 
@@ -18,7 +18,7 @@ module Alchemy
18
18
 
19
19
  before do
20
20
  klingonian_root
21
- Capybara.default_wait_time = 3 # Raising this helps this test to pass, even on travis-ci
21
+ Capybara.default_wait_time = 4 # Raising this helps this test to pass, even on travis-ci
22
22
  end
23
23
 
24
24
  it "one should be able to switch the language tree" do
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Alchemy::Admin::PagesHelper do
4
+
5
+ describe '#tinymce_javascript_tags' do
6
+ it "renders script tag for tinymce initalization" do
7
+ helper.tinymce_javascript_tags.squish.should match(/script.+Alchemy\.Tinymce/)
8
+ end
9
+ end
10
+
11
+ describe '#custom_tinymce_javascript_tags' do
12
+ it "renders script tag for custom tinymce initalization" do
13
+ helper.custom_tinymce_javascript_tags.squish.should match(/Alchemy\.Tinymce\.customInits/)
14
+ end
15
+ end
16
+
17
+ describe '#preview_sizes_for_select' do
18
+ it "returns a options string of preview screen sizes for select tag" do
19
+ helper.preview_sizes_for_select.should include('option', 'auto', '240', '320', '480', '768', '1024', '1280')
20
+ end
21
+ end
22
+
23
+ describe '#combined_page_status' do
24
+ let(:page) { FactoryGirl.build(:page, public: true, visible: true, restricted: false, locked: false)}
25
+
26
+ it "returns the translated page status" do
27
+ helper.combined_page_status(page).should == 'Page is visible in navigation.<br>Page is published.<br>Page is not restricted.'
28
+ end
29
+ end
30
+
31
+ end
@@ -263,93 +263,81 @@ module Alchemy
263
263
 
264
264
  end
265
265
 
266
- describe "#language_switcher" do
266
+ describe "#language_links" do
267
267
 
268
- before do
269
- # simulates link_to_public_child = true
270
- helper.stub(:multi_language?).and_return(true)
271
- helper.stub(:configuration) { |arg| arg == :redirect_to_public_child ? true : false }
272
- end
273
-
274
- it "should return nil when having only one public language" do
275
- helper.language_switcher.should be nil
276
- end
277
-
278
- context "with two public languages and two language_roots" do
279
-
280
- before do
281
- language_root
282
- end
283
-
284
- context "and config redirect_to_public_child is set to TRUE" do
285
-
286
- it "should return nil if only one language_root is public and both do not have children" do
287
- klingonian_language_root.update_attributes(:public => false)
288
- helper.language_switcher.should == nil
289
- end
268
+ context "with two public languages" do
269
+
270
+ # Always create second language
271
+ before { klingonian }
290
272
 
291
- it "should return nil if only one language_root is public and both have none public children" do
292
- klingonian_language_root.update_attributes(:public => false)
293
- FactoryGirl.create(:page)
294
- FactoryGirl.create(:page, :language => klingonian, :parent_id => klingonian_language_root.id)
295
- helper.language_switcher.should == nil
273
+ context "with only one language root page" do
274
+ it "should return nil" do
275
+ expect(helper.language_links).to be_nil
296
276
  end
277
+ end
297
278
 
298
- it "should render two links when having two public language_root pages" do
299
- klingonian_language_root
300
- helper.language_switcher.should have_selector('a', :count => 2)
301
- end
279
+ context "with two language root pages" do
302
280
 
303
- it "should render two links when having just one public language_root but a public children in both language_roots" do
304
- klingonian_language_root.update_attributes(:public => false)
305
- public_page
306
- klingonian_public_page
307
- helper.language_switcher.should have_selector('a', :count => 2)
308
- end
281
+ # Always create a language root page for klingonian
282
+ before { klingonian_language_root }
309
283
 
310
- it "should render two links when having two not public language_roots but a public children in both" do
311
- language_root.update_attributes(:public => false)
312
- klingonian_language_root.update_attributes(:public => false)
313
- public_page
314
- klingonian_public_page
315
- helper.language_switcher.should have_selector('a', :count => 2)
284
+ it "should render two language links" do
285
+ expect(helper.language_links).to have_selector('a', :count => 2)
316
286
  end
317
287
 
318
- it "should return nil when having two not public language_roots and a public children in only one of them" do
319
- language_root.update_attributes(:public => false)
320
- klingonian_language_root.update_attributes(:public => false)
321
- FactoryGirl.create(:page)
322
- klingonian_public_page
323
- helper.language_switcher.should == nil
288
+ it "should render language links referring to their language root page" do
289
+ code = klingonian_language_root.language_code
290
+ urlname = klingonian_language_root.urlname
291
+ expect(helper.language_links).to have_selector("a.#{code}[href='/#{code}/#{urlname}']")
324
292
  end
325
293
 
326
- end
327
-
328
- context "and config redirect_to_public_child is set to FALSE" do
329
-
330
- before do
331
- klingonian_language_root
332
- # simulates link_to_public_child = false
333
- helper.stub(:configuration).and_return(false)
294
+ context "with options[:linkname]" do
295
+ context "set to 'name'" do
296
+ it "should render the name of the language" do
297
+ expect(helper.language_links(linkname: 'name')).to have_selector("span[contains('#{klingonian_language_root.language.name}')]")
298
+ end
299
+ end
300
+
301
+ context "set to 'code'" do
302
+ it "should render the code of the language" do
303
+ expect(helper.language_links(linkname: 'code')).to have_selector("span[contains('#{klingonian_language_root.language.code}')]")
304
+ end
305
+ end
334
306
  end
335
307
 
336
- it "should render two links when having two public language_root pages" do
337
- helper.language_switcher.should have_selector('a', :count => 2)
308
+ context "spacer set to '\o/'" do
309
+ it "should render the given string as a spacer" do
310
+ expect(helper.language_links(spacer: '<span>\o/</span>')).to have_selector('span[contains("\o/")]', :count => 1)
311
+ end
338
312
  end
339
313
 
340
- it "should render nil when having just one public language_root but a public children in both language_roots" do
341
- klingonian_language_root.update_attributes(:public => false)
342
- public_page
343
- klingonian_public_page
344
- helper.language_switcher.should == nil
314
+ context "with options[:reverse]" do
315
+ context "set to false" do
316
+ it "should render the language links in an ascending order" do
317
+ expect(helper.language_links(reverse: false)).to have_selector("a.de + a.kl")
318
+ end
319
+ end
320
+
321
+ context "set to true" do
322
+ it "should render the language links in a descending order" do
323
+ expect(helper.language_links(reverse: true)).to have_selector("a.kl + a.de")
324
+ end
325
+ end
345
326
  end
346
-
347
- it "should render nil when having two not public language_roots but a public children in both" do
348
- language_root.update_attributes(:public => false)
349
- klingonian_language_root.update_attributes(:public => false)
350
- public_page
351
- klingonian_public_page
352
- helper.language_switcher.should == nil
327
+
328
+ context "with options[:show_title]" do
329
+ context "set to true" do
330
+ it "should render the language links with titles" do
331
+ helper.stub!(:_t).and_return("my title")
332
+ expect(helper.language_links(show_title: true)).to have_selector('a[title="my title"]')
333
+ end
334
+ end
335
+
336
+ context "set to false" do
337
+ it "should render the language links without titles" do
338
+ expect(helper.language_links(show_title: false)).to_not have_selector('a[title]')
339
+ end
340
+ end
353
341
  end
354
342
 
355
343
  end
@@ -133,8 +133,9 @@ module Alchemy
133
133
  describe "#descriptions" do
134
134
 
135
135
  context "without any descriptions in elements.yml file" do
136
+ before { Element.stub(:descriptions).and_return([]) }
137
+
136
138
  it "should return an empty array" do
137
- Element.stub(:descriptions).and_return([])
138
139
  Content.descriptions.should == []
139
140
  end
140
141
  end
@@ -27,5 +27,34 @@ module Alchemy
27
27
  PageLayout.selectable_layouts(Language.get_default).each { |e| e["hide"].should_not == true }
28
28
  end
29
29
 
30
+ describe ".element_names_for" do
31
+
32
+ it "should return all element names for the given pagelayout" do
33
+ PageLayout.stub(:get).with('default').and_return({'name' => 'default', 'elements' => ['element_1', 'element_2']})
34
+ expect(PageLayout.element_names_for('default')).to eq(['element_1', 'element_2'])
35
+ end
36
+
37
+ context "when given page_layout name does not exist" do
38
+ it "should return an empty array" do
39
+ expect(PageLayout.element_names_for('layout_does_not_exist!')).to eq([])
40
+ end
41
+ end
42
+
43
+ context "when page_layout description does not contain the elements key" do
44
+ it "should return an empty array" do
45
+ PageLayout.stub(:get).with('layout_without_elements_key').and_return({'name' => 'layout_without_elements_key'})
46
+ expect(PageLayout.element_names_for('layout_without_elements_key')).to eq([])
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ describe ".get" do
53
+ it "should return the page_layout description found by given name" do
54
+ PageLayout.stub(:all).and_return([{'name' => 'default'}, {'name' => 'contact'}])
55
+ expect(PageLayout.get('default')).to eq({'name' => 'default'})
56
+ end
57
+ end
58
+
30
59
  end
31
60
  end
@@ -733,8 +733,11 @@ module Alchemy
733
733
  before { page.tag_list = 'red, yellow'; page.save }
734
734
 
735
735
  it "the copy should have source tag_list" do
736
+ # The order of tags varies between postgresql and sqlite/mysql
737
+ # This is related to acts-as-taggable-on v.2.4.1
738
+ # To fix the spec we sort the tags until the issue is solved (https://github.com/mbleigh/acts-as-taggable-on/issues/363)
736
739
  subject.tag_list.should_not be_empty
737
- subject.tag_list.should == page.tag_list
740
+ subject.tag_list.sort.should == page.tag_list.sort
738
741
  end
739
742
  end
740
743
 
@@ -890,5 +893,34 @@ module Alchemy
890
893
  end
891
894
  end
892
895
 
896
+ describe "page status methods" do
897
+ let(:page) { FactoryGirl.build(:page, public: true, visible: true, restricted: false, locked: false)}
898
+
899
+ describe '#status' do
900
+ it "returns a combined status hash" do
901
+ page.status.should == {public: true, visible: true, restricted: false, locked: false}
902
+ end
903
+ end
904
+
905
+ describe '#status_title' do
906
+ it "returns a translated status string for public status" do
907
+ page.status_title(:public).should == 'Page is published.'
908
+ end
909
+
910
+ it "returns a translated status string for visible status" do
911
+ page.status_title(:visible).should == 'Page is visible in navigation.'
912
+ end
913
+
914
+ it "returns a translated status string for locked status" do
915
+ page.status_title(:locked).should == ''
916
+ end
917
+
918
+ it "returns a translated status string for restricted status" do
919
+ page.status_title(:restricted).should == 'Page is not restricted.'
920
+ end
921
+ end
922
+
923
+ end
924
+
893
925
  end
894
926
  end