alchemy_cms 2.3.2 → 2.4.beta2

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 (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