alchemy_cms 2.3.2 → 2.4.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. data/.gitignore +1 -2
  2. data/.travis.yml +1 -5
  3. data/Gemfile +4 -4
  4. data/README.md +22 -15
  5. data/alchemy_cms.gemspec +38 -38
  6. data/app/assets/javascripts/alchemy/alchemy.base.js +2 -2
  7. data/app/assets/javascripts/alchemy/alchemy.buttons.js.coffee +31 -0
  8. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js +1 -1
  9. data/app/assets/javascripts/alchemy/alchemy.elements_window.js +24 -15
  10. data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +9 -3
  11. data/app/assets/javascripts/alchemy/alchemy.jquery_loader.js +2 -2
  12. data/app/assets/javascripts/alchemy/alchemy.js +1 -0
  13. data/app/assets/javascripts/alchemy/alchemy.menubar.js +4 -12
  14. data/app/assets/javascripts/alchemy/alchemy.onload.js.coffee +32 -0
  15. data/app/assets/javascripts/alchemy/alchemy.windows.js +4 -4
  16. data/app/assets/stylesheets/alchemy/_defaults.scss +0 -1
  17. data/app/assets/stylesheets/alchemy/alchemy.css +2 -1
  18. data/app/assets/stylesheets/alchemy/base.css.scss +2 -54
  19. data/app/assets/stylesheets/alchemy/elements.css.scss +8 -5
  20. data/app/assets/stylesheets/alchemy/errors.css.scss +51 -0
  21. data/app/assets/stylesheets/alchemy/flash.css.scss +0 -2
  22. data/app/assets/stylesheets/alchemy/form_elements.css.scss +31 -75
  23. data/app/assets/stylesheets/alchemy/icons.css.scss +5 -5
  24. data/app/assets/stylesheets/alchemy/menubar.css.scss +0 -2
  25. data/app/assets/stylesheets/alchemy/sitemap.css.scss +0 -1
  26. data/app/assets/stylesheets/alchemy/tables.css.scss +3 -1
  27. data/app/controllers/alchemy/admin/base_controller.rb +19 -12
  28. data/app/controllers/alchemy/admin/elements_controller.rb +52 -24
  29. data/app/controllers/alchemy/admin/pages_controller.rb +11 -5
  30. data/app/controllers/alchemy/admin/resources_controller.rb +3 -4
  31. data/app/controllers/alchemy/admin/users_controller.rb +1 -0
  32. data/app/controllers/alchemy/base_controller.rb +34 -8
  33. data/app/controllers/alchemy/pictures_controller.rb +16 -1
  34. data/app/controllers/alchemy/user_sessions_controller.rb +6 -1
  35. data/app/helpers/alchemy/base_helper.rb +14 -0
  36. data/app/helpers/alchemy/elements_helper.rb +10 -5
  37. data/app/helpers/alchemy/pages_helper.rb +1 -2
  38. data/app/helpers/alchemy/url_helper.rb +43 -24
  39. data/app/models/alchemy/element.rb +23 -16
  40. data/app/models/alchemy/page.rb +25 -14
  41. data/app/models/alchemy/picture.rb +24 -0
  42. data/app/views/alchemy/admin/contents/create.js.erb +1 -1
  43. data/app/views/alchemy/admin/elements/_new_element_form.html.erb +1 -1
  44. data/app/views/alchemy/admin/elements/create.js.erb +11 -3
  45. data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
  46. data/app/views/alchemy/admin/elements/new.html.erb +1 -1
  47. data/app/views/alchemy/admin/elements/update.js.erb +1 -1
  48. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -1
  49. data/app/views/alchemy/admin/languages/_form.html.erb +1 -1
  50. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -1
  51. data/app/views/alchemy/admin/pages/_page.html.erb +1 -1
  52. data/app/views/alchemy/admin/pages/configure.html.erb +10 -6
  53. data/app/views/alchemy/admin/pages/configure_external.html.erb +1 -1
  54. data/app/views/alchemy/admin/pages/edit.html.erb +1 -2
  55. data/app/views/alchemy/admin/pages/new.html.erb +2 -2
  56. data/app/views/alchemy/admin/pages/update.js.erb +10 -2
  57. data/app/views/alchemy/admin/partials/_sub_navigation_tab.html.erb +5 -5
  58. data/app/views/alchemy/admin/pictures/_filter_bar.html.erb +2 -1
  59. data/app/views/alchemy/admin/pictures/_picture.html.erb +2 -2
  60. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +2 -1
  61. data/app/views/alchemy/admin/pictures/show_in_window.html.erb +3 -2
  62. data/app/views/alchemy/admin/resources/_form.html.erb +1 -1
  63. data/app/views/alchemy/admin/users/_table.html.erb +4 -4
  64. data/app/views/alchemy/admin/users/edit.html.erb +1 -1
  65. data/app/views/alchemy/admin/users/new.html.erb +1 -1
  66. data/app/views/alchemy/base/error_notice.js.erb +1 -1
  67. data/app/views/alchemy/base/remote_errors.js.erb +2 -3
  68. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +10 -7
  69. data/app/views/alchemy/essences/_essence_picture_view.html.erb +24 -21
  70. data/app/views/layouts/alchemy/admin.html.erb +9 -31
  71. data/bin/alchemy +20 -24
  72. data/config/alchemy/config.yml +6 -0
  73. data/config/alchemy/page_layouts.yml +2 -0
  74. data/config/authorization_rules.rb +1 -1
  75. data/config/locales/alchemy.de.yml +3 -0
  76. data/config/locales/alchemy.en.yml +4 -1
  77. data/db/migrate/20121026100815_alchemy_two_point_three.rb +312 -0
  78. data/lib/alchemy/mount_point.rb +9 -3
  79. data/lib/alchemy/page_layout.rb +89 -73
  80. data/lib/alchemy/version.rb +1 -1
  81. data/lib/rails/generators/alchemy/deploy_script/deploy_script_generator.rb +45 -12
  82. data/lib/rails/generators/alchemy/deploy_script/templates/deploy.rb.tt +3 -1
  83. data/lib/rails/generators/alchemy/essence/essence_generator.rb +51 -0
  84. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +18 -0
  85. data/lib/rails/generators/alchemy/essence/templates/view.html.erb +2 -0
  86. data/lib/rails/templates/alchemy.rb +1 -1
  87. data/lib/tasks/install.rake +57 -2
  88. data/spec/controllers/admin/elements_controller_spec.rb +170 -22
  89. data/spec/controllers/admin/trash_controller_spec.rb +1 -1
  90. data/spec/controllers/admin/users_controller_spec.rb +36 -0
  91. data/spec/controllers/base_controller_spec.rb +12 -1
  92. data/spec/controllers/elements_controller_spec.rb +17 -13
  93. data/spec/controllers/pictures_controller_spec.rb +4 -4
  94. data/spec/dummy/config/application.rb +1 -1
  95. data/spec/dummy/db/migrate/20121026100815_alchemy_two_point_three.rb +312 -0
  96. data/spec/dummy/db/migrate/20121026104128_create_events.rb +19 -0
  97. data/spec/dummy/db/schema.rb +1 -1
  98. data/spec/factories.rb +0 -1
  99. data/spec/helpers/base_helper_spec.rb +48 -0
  100. data/spec/helpers/elements_helper_spec.rb +14 -3
  101. data/spec/helpers/url_helper_spec.rb +8 -3
  102. data/spec/integration/picture_security_spec.rb +35 -0
  103. data/spec/integration/translation_integration_spec.rb +6 -5
  104. data/spec/models/element_spec.rb +5 -5
  105. data/spec/models/page_layout_spec.rb +10 -16
  106. data/spec/models/page_spec.rb +25 -2
  107. data/spec/models/picture_spec.rb +24 -2
  108. data/spec/routing_spec.rb +115 -115
  109. data/spec/support/alchemy/specs_helpers.rb +4 -4
  110. data/{app/assets/images/alchemy → vendor/assets/images}/Jcrop.gif +0 -0
  111. data/vendor/assets/javascripts/jquery_plugins/jquery.Jcrop.min.js +19 -243
  112. data/vendor/assets/javascripts/jquery_plugins/jquery.selectboxit.min.js +1 -0
  113. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.tabspaging.js +6 -6
  114. data/vendor/assets/stylesheets/jquery.Jcrop.min.css +28 -0
  115. metadata +48 -82
  116. data/app/assets/javascripts/alchemy/alchemy.buttons.js +0 -50
  117. data/app/assets/stylesheets/alchemy/jquery.Jcrop.css.scss +0 -54
  118. data/app/helpers/alchemy/pictures_helper.rb +0 -19
  119. data/db/migrate/20100607143125_create_pages.rb +0 -34
  120. data/db/migrate/20100607144254_create_elements.rb +0 -20
  121. data/db/migrate/20100607145256_create_contents.rb +0 -18
  122. data/db/migrate/20100607145719_create_users.rb +0 -32
  123. data/db/migrate/20100607150611_create_pictures.rb +0 -16
  124. data/db/migrate/20100607150812_create_attachments.rb +0 -16
  125. data/db/migrate/20100607153647_create_folded_pages.rb +0 -13
  126. data/db/migrate/20100607161345_create_essence_texts.rb +0 -19
  127. data/db/migrate/20100607162339_create_elements_pages.rb +0 -12
  128. data/db/migrate/20100607193638_create_essence_pictures.rb +0 -23
  129. data/db/migrate/20100607193646_create_essence_richtexts.rb +0 -16
  130. data/db/migrate/20100607193653_create_essence_htmls.rb +0 -13
  131. data/db/migrate/20100609111653_create_essence_dates.rb +0 -13
  132. data/db/migrate/20100609111809_create_essence_files.rb +0 -15
  133. data/db/migrate/20100609111821_create_essence_flashes.rb +0 -16
  134. data/db/migrate/20100609111837_create_essence_videos.rb +0 -18
  135. data/db/migrate/20100616150753_create_essence_audios.rb +0 -17
  136. data/db/migrate/20100812085225_add_crop_from_and_crop_size_to_essence_pictures.rb +0 -11
  137. data/db/migrate/20100909140701_change_essence_htmls_source_column_type.rb +0 -9
  138. data/db/migrate/20101109150312_alter_pages_visible_column_default.rb +0 -9
  139. data/db/migrate/20101109151812_create_languages.rb +0 -19
  140. data/db/migrate/20101216151419_add_language_id_to_pages.rb +0 -27
  141. data/db/migrate/20101216155216_add_index_to_languages.rb +0 -9
  142. data/db/migrate/20101216173323_add_default_to_languages.rb +0 -9
  143. data/db/migrate/20101218130049_add_urlname_index_to_pages.rb +0 -9
  144. data/db/migrate/20110115123343_remove_css_class_default_from_essence_pictures.rb +0 -11
  145. data/db/migrate/20110224105120_change_pages_visible_default.rb +0 -11
  146. data/db/migrate/20110228182659_remove_default_page_layout_from_pages.rb +0 -11
  147. data/db/migrate/20110414163140_remove_display_name_from_elements.rb +0 -11
  148. data/db/migrate/20110511100516_rename_essence_texts_title_to_link_title.rb +0 -9
  149. data/db/migrate/20110529130429_create_cells.rb +0 -14
  150. data/db/migrate/20110529130500_add_cell_id_to_elements.rb +0 -11
  151. data/db/migrate/20110530102804_change_pages_page_layout_column.rb +0 -11
  152. data/db/migrate/20110707190728_add_render_size_to_essence_pictures.rb +0 -9
  153. data/db/migrate/20110711142057_change_open_link_in_new_window_to_link_target.rb +0 -19
  154. data/db/migrate/20110919110451_add_default_role_to_users.rb +0 -9
  155. data/db/migrate/20111116125112_namespace_alchemy_models.rb +0 -23
  156. data/db/migrate/20120216135355_add_country_code_to_languages.rb +0 -9
  157. data/db/migrate/20120608085509_create_alchemy_essence_selects.rb +0 -11
  158. data/db/migrate/20120611221734_create_alchemy_essence_booleans.rb +0 -11
  159. data/db/migrate/20120704181529_add_upload_hash_to_alchemy_picture.rb +0 -5
  160. data/db/migrate/20120705214247_acts_as_taggable_on_migration.rb +0 -28
  161. data/db/migrate/20120728185830_add_cached_tag_list_to_alchemy_pictures.rb +0 -5
  162. data/db/migrate/20120831135441_set_alchemy_languages_country_code_default_to_empty_string.rb +0 -9
  163. data/spec/helpers/pictures_helper_spec.rb +0 -14
  164. data/vendor/assets/javascripts/jquery_plugins/jquery.selectBoxIt.js +0 -1909
@@ -1,6 +1,6 @@
1
1
  module Alchemy
2
2
 
3
- VERSION = "2.3.2"
3
+ VERSION = "2.4.beta2"
4
4
 
5
5
  def self.version
6
6
  VERSION
@@ -10,26 +10,59 @@ module Alchemy
10
10
  source_root File.expand_path('templates', File.dirname(__FILE__))
11
11
 
12
12
  def copy_script
13
+ @scm = options[:scm]
14
+ @database_type = options[:db]
15
+
13
16
  @server = ask('Please enter server ip or domain:')
14
- if !yes?('Do you use ssh public keys to connect to your server? (y/N)')
15
- if @store_credentials = yes?('Do want to store the ssh credentials? (PLEASE DO NOT STORE THEM IF THE REPOSITORY IS PUBLIC) (y/N)')
16
- @ssh_user = ask('Please enter ssh username:')
17
- @ssh_password = ask('Please enter ssh password:')
18
- port = ask('Please enter ssh port (22):')
19
- @ssh_port = port.blank? ? "22" : port
20
- end
17
+ if @store_credentials = yes?('Do want to store the ssh credentials? (PLEASE DO NOT STORE THEM IF THE REPOSITORY IS PUBLIC) (y/N)')
18
+ ask_for_credentials
21
19
  end
22
20
  @deploy_path = ask('Please enter the path to the public html folder:')
23
- @scm = options[:scm]
24
- @repository_url = ask('Please enter the URL to your projects repository:')
21
+ if @scm == "git"
22
+ @repository_url = get_git_remote
23
+ end
24
+ if @repository_url.nil?
25
+ @repository_url = ask('Please enter the URL to your projects repository:')
26
+ end
25
27
  if @scm == "svn" && yes?('Is your repository private? (y/N)')
26
- @scm_user = ask('Please enter the username for your repository:')
27
- @scm_password = ask('Please enter the password to your repository:')
28
+ ask_for_repo_credentials
28
29
  end
29
- @database_type = options[:db]
30
30
  template "deploy.rb.tt", Rails.root.join('config', 'deploy.rb')
31
+ setup_capistrano
32
+ show_read_me
33
+ end
34
+
35
+ private
36
+
37
+ def ask_for_credentials
38
+ @ssh_user = ask('Please enter ssh username:')
39
+ port = ask('Please enter ssh port (22):')
40
+ @ssh_port = port.blank? ? "22" : port
41
+ @no_ssh_public_keys = !yes?('Do you use ssh public keys to connect to your server? (y/N)')
42
+ if @no_ssh_public_keys
43
+ @ssh_password = ask('Please enter ssh password:')
44
+ end
45
+ end
46
+
47
+ def ask_for_repo_credentials
48
+ @scm_user = ask('Please enter the username for your repository:')
49
+ @scm_password = ask('Please enter the password to your repository:')
50
+ end
51
+
52
+ def get_git_remote
53
+ remotes = `git remote -v`.split("\n")
54
+ remote = remotes.first
55
+ if remote
56
+ remote.split("\t")[1].split(" ")[0]
57
+ end
58
+ end
59
+
60
+ def setup_capistrano
31
61
  puts "\nSetting up Capistrano"
32
62
  `capify .`
63
+ end
64
+
65
+ def show_read_me
33
66
  puts "\nWe are done!\n"
34
67
  puts "\nPlease run 'cap deploy:setup'\n to setup the server for deployment."
35
68
  puts "\nIf you want to deploy Alchemy the first time type:\ncap deploy:cold"
@@ -3,16 +3,18 @@ require 'alchemy/capistrano'
3
3
  load 'deploy/assets'
4
4
 
5
5
  # ssh settings
6
- <%- if @ssh_user.blank? -%>
6
+ <%- if @ssh_user.blank? || !@store_credentials -%>
7
7
  set(:user) { Capistrano::CLI.ui.ask('Enter your ssh username: ') }
8
8
  <%- else -%>
9
9
  set :user, "<%= @ssh_user %>"
10
10
  <%- end -%>
11
+ <%- if @no_ssh_public_keys -%>
11
12
  <%- if @ssh_password.blank? -%>
12
13
  set(:password) { Capistrano::CLI.password_prompt("Enter the password for #{user}: ") }
13
14
  <%- else -%>
14
15
  set :password, "<%= @ssh_password %>"
15
16
  <%- end -%>
17
+ <%- end -%>
16
18
  <%- if @ssh_port != "22" && !@store_credentials -%>
17
19
  set(:port) { Capistrano::CLI.ui.ask('Enter the ssh port: ') }
18
20
  <%- elsif @ssh_port != "22" && @store_credentials -%>
@@ -0,0 +1,51 @@
1
+ require 'rails'
2
+
3
+ module Alchemy
4
+ module Generators
5
+ class EssenceGenerator < ::Rails::Generators::Base
6
+ desc "This generator generates an Alchemy essence for you."
7
+ argument :essence_name, :banner => "YourEssenceName"
8
+ source_root File.expand_path('templates', File.dirname(__FILE__))
9
+
10
+ def init
11
+ @essence_name = essence_name.underscore
12
+ @essence_view_path = Rails.root.join('app/views/alchemy/essences')
13
+ end
14
+
15
+ def create_model
16
+ invoke("model", [@essence_name])
17
+ end
18
+
19
+ def create_directory
20
+ empty_directory @essence_view_path
21
+ end
22
+
23
+ def act_as_essence
24
+ essence_class_file = Rails.root.join('app/models', "#{@essence_name}.rb")
25
+ essence_class = @essence_name.classify
26
+ inject_into_class essence_class_file, essence_class, <<-CLASSMETHOD
27
+ acts_as_essence(
28
+ # Your options:
29
+ #
30
+ # :ingredient_column => Symbol # Specifies the column name you use for storing the content in the database. [Default] :body
31
+ # :validate_column => Symbol # Which column should be validated. [Default] ingredient_column
32
+ # :preview_text_column => Symbol # Specifies the column for the preview_text method. [Default] ingredient_column
33
+ # :preview_text_method => Symbol # A method called on ingredient to get the preview text.
34
+ )
35
+ CLASSMETHOD
36
+ end
37
+
38
+ def copy_templates
39
+ template "view.html.erb", "#{@essence_view_path}/_#{@essence_name}_view.html.erb"
40
+ template "editor.html.erb", "#{@essence_view_path}/_#{@essence_name}_editor.html.erb"
41
+ end
42
+
43
+ def show_todo
44
+ say "\nPlease open the generated migration file and add your columns to your table."
45
+ say "Then run 'rake db:migrate' to update your database."
46
+ say "Also check the generated view files and alter them to fit your needs."
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,18 @@
1
+ <%%#
2
+ Available locals:
3
+ * content (The object the essence is linked to the element)
4
+ * html_options
5
+
6
+ Please consult Alchemy::Content.rb docs for further methods on the content object
7
+ %>
8
+ <%% cache(content) do %>
9
+
10
+ <div class="content_editor <%= @essence_name %>" id="<%%= content_dom_id(content) %>">
11
+ <%%#= text_field_tag(
12
+ content.form_field_name,
13
+ content.ingredient,
14
+ :id => content.form_field_id
15
+ ) %>
16
+ </div>
17
+
18
+ <%% end %>
@@ -0,0 +1,2 @@
1
+ <%%# The content object holds the essence %>
2
+ <%%= content.ingredient %>
@@ -5,7 +5,7 @@ require 'alchemy/version'
5
5
 
6
6
  gem 'alchemy_cms', "~> #{Alchemy::VERSION}"
7
7
  gem 'ruby-debug', :group => :development, :platform => :ruby_18
8
- gem 'ruby-debug19', :group => :development, :platform => :ruby_19
8
+ gem 'debugger', :group => :development, :platform => :ruby_19
9
9
 
10
10
  if yes?("\nDo you want to use Capistrano for deployment? (y/N)")
11
11
  gem 'capistrano', :group => :development
@@ -1,8 +1,60 @@
1
+ require 'thor'
2
+
3
+ class Alchemy::RoutesInjector < Thor
4
+ include Thor::Actions
5
+
6
+ def initialize; super; end
7
+
8
+ no_tasks do
9
+ def inject
10
+ mountpoint = ask "\nWhere do you want to mount Alchemy CMS? (/)"
11
+ mountpoint = "/" if mountpoint.empty?
12
+ sentinel = /\.routes\.draw do(?:\s*\|map\|)?\s*$/
13
+ inject_into_file "./config/routes.rb", "\n mount Alchemy::Engine => '#{mountpoint}'\n", { :after => sentinel, :verbose => true }
14
+ end
15
+ end
16
+ end
17
+
1
18
  namespace :alchemy do
2
19
 
20
+ desc "Installs Alchemy CMS into your app."
21
+ task :install do
22
+ Rake::Task["alchemy:install:migrations"].invoke
23
+ Rake::Task["alchemy:mount"].invoke
24
+ system("rails g alchemy:scaffold")
25
+ Rake::Task["db:migrate"].invoke
26
+ Rake::Task["alchemy:db:seed"].invoke
27
+ puts <<-EOF
28
+
29
+ \\o/ Successfully installed Alchemy CMS \\o/
30
+
31
+ Now:
32
+
33
+ 1. Start your Rails server:
34
+
35
+ rails server
36
+
37
+ 2. Open your browser and enter the following URL:
38
+
39
+ http://localhost:3000/admin/signup
40
+
41
+ 3. Follow the instructions to complete the installation!
42
+
43
+ Thank you for using Alchemy CMS!
44
+
45
+ http://alchemy-cms.com
46
+
47
+ EOF
48
+ end
49
+
50
+ desc "Mounts Alchemy into your routes."
51
+ task :mount do
52
+ Alchemy::RoutesInjector.new.inject
53
+ end
54
+
3
55
  namespace :db do
4
56
 
5
- desc "Seeds the database with essential data for Alchemy."
57
+ desc "Seeds your database with essential data for Alchemy CMS."
6
58
  task :seed => :environment do
7
59
  Alchemy::Seeder.seed!
8
60
  end
@@ -11,9 +63,12 @@ namespace :alchemy do
11
63
 
12
64
  namespace :standard_set do
13
65
 
14
- desc "Install Alchemys standard set."
66
+ desc "Install Alchemy CMS's standard set."
15
67
  task :install do
16
68
  system("rails g alchemy:scaffold --with-standard-set")
69
+ puts "\n-> Please do not forget to add Alchemy's standard set to precompiable assets. <-\n"
70
+ puts "\nPut this line in your 'config/environments/production.rb' file:\n"
71
+ puts " config.assets.precompile += %w( alchemy/standard_set.css )"
17
72
  end
18
73
 
19
74
  end
@@ -8,8 +8,91 @@ module Alchemy
8
8
  Alchemy::UserSession.create FactoryGirl.create(:admin_user)
9
9
  end
10
10
 
11
- let(:page) { mock_model('Page', {:id => 1, :urlname => 'lulu'}) }
12
- let(:element) { mock_model('Element', {:id => 1, :page_id => page.id, :public => true, :display_name_with_preview_text => 'lalaa', :dom_id => 1}) }
11
+ let(:page) { FactoryGirl.create(:page, :urlname => 'lulu') }
12
+ let(:element) { FactoryGirl.create(:element, :page_id => page.id) }
13
+ let(:element_in_clipboard) { FactoryGirl.create(:element, :page_id => page.id) }
14
+ let(:clipboard) { session[:clipboard] = Clipboard.new }
15
+
16
+ describe '#create' do
17
+
18
+ before { element }
19
+
20
+ it "should insert the element at bottom of list" do
21
+ post :create, {:element => {:name => 'news', :page_id => page.id}, :format => :js}
22
+ page.elements.count.should == 2
23
+ page.elements.last.name.should == 'news'
24
+ end
25
+
26
+ context "on a page with a setting for insert_elements_at of top" do
27
+
28
+ before do
29
+ PageLayout.stub(:get).and_return({
30
+ 'name' => 'news',
31
+ 'elements' => ['news'],
32
+ 'insert_elements_at' => 'top'
33
+ })
34
+ end
35
+
36
+ it "should insert the element at top of list" do
37
+ post :create, {:element => {:name => 'news', :page_id => page.id}, :format => :js}
38
+ page.elements.count.should == 2
39
+ page.elements.first.name.should == 'news'
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#find_or_create_cell' do
45
+
46
+ before do
47
+ Cell.stub!(:definition_for).and_return({'name' => 'header', 'elements' => ['header']})
48
+ controller.instance_variable_set(:@page, page)
49
+ end
50
+
51
+ context "with element name and cell name in the params" do
52
+
53
+ before do
54
+ controller.stub(:params).and_return({
55
+ :element => {:name => 'header#header'}
56
+ })
57
+ end
58
+
59
+ context "with cell not existing" do
60
+ it "should create the cell" do
61
+ expect {
62
+ controller.send(:find_or_create_cell)
63
+ }.to change(page.cells, :count).from(0).to(1)
64
+ end
65
+ end
66
+
67
+ context "with the cell already present" do
68
+
69
+ before { FactoryGirl.create(:cell, :page => page, :name => 'header') }
70
+
71
+ it "should load the cell" do
72
+ expect {
73
+ controller.send(:find_or_create_cell)
74
+ }.to_not change(page.cells, :count)
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ context "with only the element name in the params" do
82
+
83
+ before do
84
+ controller.stub(:params).and_return({
85
+ :element => {:name => 'header'}
86
+ })
87
+ end
88
+
89
+ it "should return nil" do
90
+ controller.send(:find_or_create_cell).should be_nil
91
+ end
92
+
93
+ end
94
+
95
+ end
13
96
 
14
97
  describe '#list' do
15
98
 
@@ -33,19 +116,19 @@ module Alchemy
33
116
  end
34
117
 
35
118
  it "should set a new position to the element" do
36
- post :order, {:element_ids => ["#{@element.id}"]}
119
+ post :order, {:element_ids => ["#{@element.id}"], :format => :js}
37
120
  @element.reload
38
121
  @element.position.should_not == nil
39
122
  end
40
123
 
41
124
  it "should assign the (new) page_id to the element" do
42
- post :order, {:element_ids => ["#{@element.id}"], :page_id => 1, :cell_id => nil}
125
+ post :order, {:element_ids => ["#{@element.id}"], :page_id => 1, :cell_id => nil, :format => :js}
43
126
  @element.reload
44
127
  @element.page_id.should == 1
45
128
  end
46
129
 
47
130
  it "should assign the (new) cell_id to the element" do
48
- post :order, {:element_ids => ["#{@element.id}"], :page_id => 1, :cell_id => 5}
131
+ post :order, {:element_ids => ["#{@element.id}"], :page_id => 1, :cell_id => 5, :format => :js}
49
132
  @element.reload
50
133
  @element.cell_id.should == 5
51
134
  end
@@ -75,27 +158,95 @@ module Alchemy
75
158
 
76
159
  context "with cells" do
77
160
 
78
- before do
79
- @page = FactoryGirl.create(:public_page, :do_not_autogenerate => false)
80
- @cell = FactoryGirl.create(:cell, :name => 'header', :page => @page)
81
- Page.any_instance.stub(:can_have_cells?).and_return(true)
82
- Cell.stub!(:definition_for).and_return({'name' => 'header', 'elements' => ['article']})
83
- end
161
+ context "" do
162
+
163
+ before do
164
+ @page = FactoryGirl.create(:public_page, :do_not_autogenerate => false)
165
+ @cell = FactoryGirl.create(:cell, :name => 'header', :page => @page)
166
+ PageLayout.stub(:get).and_return({
167
+ 'name' => 'standard',
168
+ 'elements' => ['article'],
169
+ 'cells' => ['header']
170
+ })
171
+ Cell.stub!(:definition_for).and_return({'name' => 'header', 'elements' => ['article']})
172
+ end
84
173
 
85
- context "and cell name in element name" do
174
+ context "and cell name in element name" do
175
+
176
+ it "should put the element in the correct cell" do
177
+ post :create, {:element => {:name => "article#header", :page_id => @page.id}, :format => :js}
178
+ @cell.elements.first.should be_an_instance_of(Element)
179
+ end
180
+
181
+ end
182
+
183
+ context "and no cell name in element name" do
184
+
185
+ it "should put the element in the main cell" do
186
+ post :create, {:element => {:name => "article", :page_id => @page.id}, :format => :js}
187
+ @page.elements.not_in_cell.first.should be_an_instance_of(Element)
188
+ end
86
189
 
87
- it "should put the element in the correct cell" do
88
- post :create, {:element => {:name => "article#header", :page_id => @page.id}}
89
- @cell.elements.first.should be_an_instance_of(Element)
90
190
  end
91
191
 
92
192
  end
93
193
 
94
- context "and no cell name in element name" do
194
+ context "with paste_from_clipboard in parameters" do
195
+
196
+ context "" do
197
+ before do
198
+ @page = FactoryGirl.create(:public_page, :do_not_autogenerate => false)
199
+ @cell = FactoryGirl.create(:cell, :name => 'header', :page => @page)
200
+ PageLayout.stub(:get).and_return({
201
+ 'name' => 'standard',
202
+ 'elements' => ['article'],
203
+ 'cells' => ['header']
204
+ })
205
+ Cell.stub!(:definition_for).and_return({'name' => 'header', 'elements' => ['article']})
206
+ clipboard[:elements] = [{:id => element_in_clipboard.id}]
207
+ end
208
+
209
+ it "should create the element in the correct cell" do
210
+ post :create, {:element => {:page_id => @page.id}, :paste_from_clipboard => "#{element_in_clipboard.id}##{@cell.name}", :format => :js}
211
+ @cell.elements.first.should be_an_instance_of(Element)
212
+ end
95
213
 
96
- it "should put the element in the main cell" do
97
- post :create, {:element => {:name => "article", :page_id => @page.id}}
98
- @page.elements.not_in_cell.first.should be_an_instance_of(Element)
214
+ context "" do
215
+
216
+ before { @cell.elements.create(:page_id => @page.id, :name => "article", :create_contents_after_create => false) }
217
+
218
+ it "should set the correct position for the element" do
219
+ post :create, {:element => {:page_id => @page.id}, :paste_from_clipboard => "#{element_in_clipboard.id}##{@cell.name}", :format => :js}
220
+ @cell.elements.last.position.should == @cell.elements.count
221
+ end
222
+
223
+ end
224
+ end
225
+
226
+ context "on a page with a setting for insert_elements_at of top" do
227
+ let(:page) { FactoryGirl.create(:public_page, :name => 'News') }
228
+ let(:element_in_clipboard) { FactoryGirl.create(:element, :page => page, :name => 'news') }
229
+ let(:cell) { page.cells.first }
230
+ let(:element) { FactoryGirl.create(:element, :name => 'news', :page => page, :cell => cell) }
231
+
232
+ before do
233
+ PageLayout.stub(:get).and_return({
234
+ 'name' => 'news',
235
+ 'elements' => ['news'],
236
+ 'insert_elements_at' => 'top',
237
+ 'cells' => ['news']
238
+ })
239
+ Cell.stub!(:definition_for).and_return({'name' => 'news', 'elements' => ['news']})
240
+ clipboard[:elements] = [{:id => element_in_clipboard.id}]
241
+ cell.elements << element
242
+ end
243
+
244
+ it "should insert the element at top of list" do
245
+ post :create, {:element => {:name => 'news', :page_id => page.id}, :paste_from_clipboard => "#{element_in_clipboard.id}##{cell.name}", :format => :js}
246
+ cell.elements.count.should == 2
247
+ cell.elements.first.name.should == 'news'
248
+ cell.elements.first.should_not == element
249
+ end
99
250
  end
100
251
 
101
252
  end
@@ -106,9 +257,6 @@ module Alchemy
106
257
 
107
258
  render_views
108
259
 
109
- let(:clipboard) { session[:clipboard] = Clipboard.new }
110
- let(:element_in_clipboard) { @element ||= FactoryGirl.create(:element, :page_id => page.id) }
111
-
112
260
  before(:each) do
113
261
  clipboard[:elements] = [{:id => element_in_clipboard.id, :action => 'cut'}]
114
262
  end