alchemy_cms 2.7.5 → 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 491ad71e83bcd6aaaeb4f79f9c696982ea8c8112
4
- data.tar.gz: 64c210c6d964efa046475945ede684ecf3e626ed
3
+ metadata.gz: edf3ac4fd7a2b98807ac909f6f091cdafb11f9c6
4
+ data.tar.gz: 4515777e5e93ef98b427f57dd9fd5a9f4b59333f
5
5
  SHA512:
6
- metadata.gz: be1fe2cef675009c89d8f1a70f6b8b90ded20c81e91e74c0619347e9d7047d73da29683391d8512281147a7a71d0a88b3dbd840b94c5a0427814ada8eb9fb1a0
7
- data.tar.gz: 91beddf874b48a4f4b761a5952c73a18059e5b355d0e28b417d8a34c1a4c61fda2f20e18369ee13488c2521555b3ddd8f9fb1c139b09f14d750d6402e6aba36c
6
+ metadata.gz: a32052e6ccd970e0ba9f51e978d57897b67ffd0980425c283ddb1c01d27e5a8f71006d553867c6833420c33fc95802917987de9a599322fd1f44908e0e4d9455
7
+ data.tar.gz: d8199c8dce2e4d9f52aa0d6da2eca587050a574ef6d67855fe28c484718a8cb4d19a5fba1848e39ff1163512a148fabf014bc5d5ebd1c0002e55f304459be1eb
data/.travis.yml CHANGED
@@ -4,7 +4,7 @@ rvm:
4
4
  - 2.0.0
5
5
  branches:
6
6
  only:
7
- - 2.7-stable
7
+ - 2.8-stable
8
8
  script: rake
9
9
  env:
10
10
  - DB=mysql
data/Gemfile CHANGED
@@ -14,8 +14,6 @@ gem 'sqlite3' if ENV['DB'].nil? || ENV['DB'] == 'sqlite'
14
14
  gem 'mysql2' if ENV['DB'] == 'mysql'
15
15
  gem 'pg' if ENV['DB'] == 'postgresql'
16
16
 
17
- gem 'database_cleaner'
18
-
19
17
  unless ENV['CI']
20
18
  gem 'pry'
21
19
  gem 'quiet_assets' # Mute assets loggin
@@ -25,6 +23,7 @@ end
25
23
  group :test do
26
24
  unless ENV['FAST_SPECS']
27
25
  gem 'poltergeist'
26
+ gem 'connection_pool' # https://gist.github.com/mperham/3049152
28
27
  unless ENV['CI']
29
28
  gem 'launchy'
30
29
  end
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ![Alchemy CMS](http://alchemy-cms.com/assets/alchemy_logo.png)
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/alchemy_cms.png)](http://badge.fury.io/rb/alchemy_cms)
4
- [![Build Status](https://secure.travis-ci.org/magiclabs/alchemy_cms.png?branch=2.7-stable)](http://travis-ci.org/magiclabs/alchemy_cms) [![Code Climate](https://codeclimate.com/github/magiclabs/alchemy_cms.png)](https://codeclimate.com/github/magiclabs/alchemy_cms) [![Coverage Status](https://coveralls.io/repos/magiclabs/alchemy_cms/badge.png?branch=2.7-stable)](https://coveralls.io/r/magiclabs/alchemy_cms)
4
+ [![Build Status](https://secure.travis-ci.org/magiclabs/alchemy_cms.png?branch=2.8-stable)](http://travis-ci.org/magiclabs/alchemy_cms) [![Code Climate](https://codeclimate.com/github/magiclabs/alchemy_cms.png)](https://codeclimate.com/github/magiclabs/alchemy_cms) [![Coverage Status](https://coveralls.io/repos/magiclabs/alchemy_cms/badge.png?branch=2.8-stable)](https://coveralls.io/r/magiclabs/alchemy_cms)
5
5
 
6
6
  About
7
7
  -----
@@ -67,7 +67,7 @@ Add to existing Rails project
67
67
 
68
68
  In your Gemfile:
69
69
 
70
- gem 'alchemy_cms', github: 'magiclabs/alchemy_cms', branch: '2.7-stable'
70
+ gem 'alchemy_cms', github: 'magiclabs/alchemy_cms', branch: '2.8-stable'
71
71
 
72
72
  Run in terminal:
73
73
 
@@ -133,4 +133,4 @@ Authors
133
133
  License
134
134
  -------
135
135
 
136
- * BSD: <https://raw.github.com/magiclabs/alchemy_cms/2.7-stable/LICENSE>
136
+ * BSD: <https://raw.github.com/magiclabs/alchemy_cms/2.8-stable/LICENSE>
@@ -200,19 +200,17 @@ module Alchemy
200
200
  @sorting = true
201
201
  end
202
202
 
203
- # Receives a JSON object representing a language tree to be ordered
204
- # and updates all pages in that language structure to their correct indexes
205
203
  def order
206
- neworder = JSON.parse(params[:set])
207
- rootpage = Page.language_root_for(session[:language_id])
208
-
209
- tree = create_tree(neworder, rootpage)
204
+ @page_root = Page.language_root_for(session[:language_id])
210
205
 
211
- Alchemy::Page.transaction do
212
- tree.each do |key, node|
213
- dbitem = Page.find(key)
214
- dbitem.update_node!(node)
215
- end
206
+ # Taken from https://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop
207
+ neworder = JSON.parse(params[:set])
208
+ prev_item = nil
209
+ neworder.each do |item|
210
+ dbitem = Page.find(item['id'])
211
+ prev_item.nil? ? dbitem.move_to_child_of(@page_root) : dbitem.move_to_right_of(prev_item)
212
+ sort_children(item, dbitem) unless item['children'].nil?
213
+ prev_item = dbitem.reload
216
214
  end
217
215
 
218
216
  flash[:notice] = _t("Pages order saved")
@@ -242,85 +240,6 @@ module Alchemy
242
240
 
243
241
  private
244
242
 
245
- # Returns the current left index and the aggregated hash of tree nodes indexed by page id visited so far
246
- #
247
- # Visits a batch of children nodes, assigns them the correct ordering indexes and spuns recursively the same
248
- # procedure on their children, if any
249
- #
250
- # @param [Array]
251
- # An array of children nodes to be visited
252
- # @param [Integer]
253
- # The lft attribute that should be given to the first node in the array
254
- # @param [Integer]
255
- # The page id of the parent of this batch of children nodes
256
- # @param [Integer]
257
- # The depth at which these children reside
258
- # @param [Hash]
259
- # A Hash of TreeNode's indexed by their page ids
260
- # @param [String]
261
- # The url for the parent node of these children
262
- # @param [Boolean]
263
- # Whether these children reside in a restricted branch according to their ancestors
264
- #
265
- def visit_nodes(nodes, my_left, parent, depth, tree, url, restricted)
266
- nodes.each do |item|
267
- my_right = my_left + 1
268
- my_restricted = item['restricted'] || restricted
269
- urls = process_url(url, item)
270
-
271
- if item['children']
272
- my_right, tree = visit_nodes(item['children'], my_left + 1, item['id'], depth + 1, tree, urls[:children_path], my_restricted)
273
- end
274
-
275
- tree[item['id']] = TreeNode.new(my_left, my_right, parent, depth, urls[:my_urlname], my_restricted)
276
- my_left = my_right + 1
277
- end
278
-
279
- [my_left, tree]
280
- end
281
-
282
- # Returns a Hash of TreeNode's indexed by their page ids
283
- #
284
- # Grabs the array representing a tree structure of pages passed as a parameter,
285
- # visits it and creates a map of TreeNodes indexed by page id featuring Nested Set
286
- # ordering information consisting of the left, right, depth and parent_id indexes as
287
- # well as a node's url and restricted status
288
- #
289
- # @param [Array]
290
- # An Array representing a tree of Alchemy::Page's
291
- # @param [Alchemy::Page]
292
- # The root page for the language being ordered
293
- #
294
- def create_tree(items, rootpage)
295
- _, tree = visit_nodes(items, rootpage.lft + 1, rootpage.id, rootpage.depth + 1, {}, "", rootpage.restricted)
296
- tree
297
- end
298
-
299
- # Returns a pair, the path that a given tree node should take, and the path its children should take
300
- #
301
- # This function will add a node's own slug into their ancestor's path
302
- # in order to create the full URL of a node
303
- #
304
- # NOTE: external and invisible pages are not part of the full path of their children
305
- #
306
- # @param [String]
307
- # The node's ancestors path
308
- # @param [Hash]
309
- # A children node
310
- #
311
- def process_url(ancestors_path, item)
312
- default_urlname = (ancestors_path.blank? ? "" : "#{ancestors_path}/") + item['slug']
313
-
314
- pair = {my_urlname: default_urlname, children_path: default_urlname}
315
-
316
- if item['external'] == true || item['visible'] == false
317
- # children ignore an ancestor in their path if external or invisible
318
- pair[:children_path] = ancestors_path
319
- end
320
-
321
- pair
322
- end
323
-
324
243
  def load_page
325
244
  @page = Page.find(params[:id])
326
245
  end
@@ -329,6 +248,17 @@ module Alchemy
329
248
  request.raw_post.split('&').map { |i| i = {i.split('=')[0].gsub(/[^0-9]/, '') => i.split('=')[1]} }
330
249
  end
331
250
 
251
+ # Taken from https://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop
252
+ def sort_children(element, dbitem)
253
+ prevchild = nil
254
+ element['children'].each do |child|
255
+ childitem = Page.find(child['id'])
256
+ prevchild.nil? ? childitem.move_to_child_of(dbitem) : childitem.move_to_right_of(prevchild)
257
+ sort_children(child, childitem) unless child['children'].nil?
258
+ prevchild = childitem
259
+ end
260
+ end
261
+
332
262
  def redirect_path_after_page_create
333
263
  if @page.redirects_to_external?
334
264
  admin_pages_path
@@ -84,52 +84,6 @@ module Alchemy
84
84
  end
85
85
  end
86
86
 
87
- # Sets the language for rendering pages in pages controller.
88
- #
89
- def set_language(lang = nil)
90
- if lang
91
- @language = lang.is_a?(Language) ? lang : load_language_from(lang)
92
- else
93
- # find the best language and remember it for later
94
- @language = load_language_from_params ||
95
- load_language_from_session ||
96
- load_language_default
97
- end
98
-
99
- # store language in session
100
- store_language_in_session(@language)
101
-
102
- # switch locale to selected language
103
- ::I18n.locale = @language.code
104
- end
105
-
106
- def load_language_from_params
107
- if params[:lang].present?
108
- Language.find_by_code(params[:lang])
109
- end
110
- end
111
-
112
- def load_language_from_session
113
- if session[:language_id].present?
114
- Language.find_by_id(session[:language_id])
115
- end
116
- end
117
-
118
- def load_language_from(language_code_or_id)
119
- Language.find_by_id(language_code_or_id) || Language.find_by_code(language_code_or_id)
120
- end
121
-
122
- def load_language_default
123
- Language.get_default || raise(DefaultLanguageNotFoundError)
124
- end
125
-
126
- def store_language_in_session(language)
127
- if language && language.id
128
- session[:language_id] = language.id
129
- session[:language_code] = language.code
130
- end
131
- end
132
-
133
87
  def store_location
134
88
  session[:redirect_path] = request.path
135
89
  end
@@ -45,6 +45,7 @@ module Alchemy
45
45
  # Should the window show overflowing content?
46
46
  #
47
47
  def link_to_overlay_window(content, url, options={}, html_options={})
48
+ ActiveSupport::Deprecation.warn("Used deprecated link_to_overlay_window helper. It will be removed in Alchemy v3.0. Please use link_to_dialog instead.")
48
49
  default_options = {
49
50
  :modal => true,
50
51
  :overflow => true,
@@ -139,6 +140,7 @@ module Alchemy
139
140
  # The label for the cancel button
140
141
  #
141
142
  def link_to_confirmation_window(link_string = "", message = "", url = "", html_options = {})
143
+ ActiveSupport::Deprecation.warn("Used deprecated link_to_confirmation_window helper. It will be removed in Alchemy v3.0. Please use link_to_confirm_dialog instead.")
142
144
  link_to(link_string, url,
143
145
  html_options.merge(
144
146
  'data-alchemy-confirm-delete' => {
@@ -22,6 +22,7 @@ module Alchemy
22
22
  # * editor_options (Hash) - Will be passed to the render_essence_editor partial renderer
23
23
  #
24
24
  def render_essence_editor_by_type(element, essence_type, options = {}, editor_options = {})
25
+ ActiveSupport::Deprecation.warn("Used deprecated render_essence_editor_by_type helper. It will be removed in Alchemy v3.0. You can use render_essence_editor_by_name instead.")
25
26
  return warning('Element is nil', _t(:no_element_given)) if element.blank?
26
27
  return warning('EssenceType is blank', _t("No EssenceType given")) if essence_type.blank?
27
28
  defaults = {
@@ -76,6 +77,7 @@ module Alchemy
76
77
  # Otherwise the pages are ordered by their position in the nested set.
77
78
  #
78
79
  def page_selector(element, content_name, options = {}, select_options = {})
80
+ ActiveSupport::Deprecation.warn("Used deprecated page_selector helper. It will be removed in Alchemy v3.0. Please use a select_tag with pages_for_select instead.")
79
81
  default_options = {
80
82
  :page_attribute => :id,
81
83
  :global => false,
@@ -213,6 +213,7 @@ module Alchemy
213
213
  # @note When passing a String for options :from_page, it must be a page_layout name.
214
214
  #
215
215
  def all_elements_by_name(name, options = {})
216
+ ActiveSupport::Deprecation.warn("Used deprecated all_elements_by_name helper. It will be removed in Alchemy v3.0. Please build the relevant behavior on your own.")
216
217
  warning('options[:language] option not allowed any more in all_elements_by_name helper') unless options[:language].blank?
217
218
  options = {
218
219
  count: :all,
@@ -244,6 +245,7 @@ module Alchemy
244
245
  # The id of the Page the element is associated with
245
246
  #
246
247
  def element_from_page(options = {})
248
+ ActiveSupport::Deprecation.warn("Used deprecated element_from_page helper. It will be removed in Alchemy v3.0. Please build the relevant behavior on your own.")
247
249
  default_options = {
248
250
  page_urlname: "",
249
251
  page_id: nil,
@@ -263,6 +265,7 @@ module Alchemy
263
265
 
264
266
  # Renders all element partials from given cell.
265
267
  def render_cell_elements(cell)
268
+ ActiveSupport::Deprecation.warn("Used deprecated render_cell_elements helper. It will be removed in Alchemy v3.0. You can use render_elements(from_cell: cell) instead.")
266
269
  return warning("No cell given.") if cell.blank?
267
270
  render_elements({:from_cell => cell})
268
271
  end
@@ -60,6 +60,7 @@ module Alchemy
60
60
  # <%= render_essence_view_by_type(element, "EssencePicture", 1, {:image_size => "120x80", :crop => true}) %>
61
61
  #
62
62
  def render_essence_view_by_type(element, type, position = 1, options = {}, html_options = {})
63
+ ActiveSupport::Deprecation.warn("Used deprecated render_essence_view_by_type helper. It will be removed in Alchemy v3.0. You can use render_essence_view_by_name instead.")
63
64
  if element.blank?
64
65
  warning('Element is nil')
65
66
  return ""
@@ -33,12 +33,12 @@ module Alchemy
33
33
  end
34
34
 
35
35
  def language_switches(options={})
36
- ActiveSupport::Deprecation.warn("Used deprecated language_switches helper. Please use language_links instead.")
36
+ ActiveSupport::Deprecation.warn("Used deprecated language_switches helper. It will be removed in Alchemy v3.0. You can use language_links instead.")
37
37
  language_links(options)
38
38
  end
39
39
 
40
40
  def language_switcher(options={})
41
- ActiveSupport::Deprecation.warn("Used deprecated language_switcher helper. Please use language_links instead.")
41
+ ActiveSupport::Deprecation.warn("Used deprecated language_switcher helper. It will be removed in Alchemy v3.0. You can use language_links instead.")
42
42
  language_links(options)
43
43
  end
44
44
 
@@ -411,6 +411,7 @@ module Alchemy
411
411
 
412
412
  # Renders a menubar for logged in users that are visiting a page.
413
413
  def alchemy_menu_bar
414
+ ActiveSupport::Deprecation.warn('Used deprecated alchemy_menu_bar helper. It will be removed in Alchemy v3.0. You can use `render "/alchemy/menubar"` instead.')
414
415
  return if @preview_mode
415
416
  if permitted_to?(:edit, :alchemy_admin_pages)
416
417
  menu_bar_string = ""
@@ -25,7 +25,7 @@ module Alchemy
25
25
  # <%= link_to '&raquo order now', page_path_for(:page_layout => 'orderform', :product_id => element.id) %>
26
26
  #
27
27
  def page_path_for(options={})
28
- ActiveSupport::Deprecation.warn("Used deprecated page_path_for helper. Please use show_alchemy_page_path instead.")
28
+ ActiveSupport::Deprecation.warn("Used deprecated page_path_for helper. It will be removed in Alchemy v3.0. You can use show_alchemy_page_path instead.")
29
29
  return warning("No page_layout, or urlname given. I got #{options.inspect} ") if options[:page_layout].blank? && options[:urlname].blank?
30
30
  if options[:urlname].blank?
31
31
  page = Page.find_by_page_layout(options[:page_layout])
@@ -298,25 +298,6 @@ module Alchemy
298
298
  set_language_code
299
299
  end
300
300
 
301
- # Updates an Alchemy::Page based on a new ordering to be applied to it
302
- #
303
- # Note: Page's urls should not be updated (and a legacy URL created) if nesting is OFF
304
- # or if a page is external or if the URL is the same
305
- #
306
- # @param [TreeNode]
307
- # A tree node with new lft, rgt, depth, url, parent_id and restricted indexes to be updated
308
- #
309
- def update_node!(node)
310
- hash = {lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted}
311
-
312
- if Config.get(:url_nesting) && !self.redirects_to_external? && self.urlname != node.url
313
- LegacyPageUrl.create(page_id: self.id, urlname: self.urlname)
314
- hash.merge!(urlname: node.url)
315
- end
316
-
317
- self.class.update_all(hash, {id: self.id})
318
- end
319
-
320
301
  private
321
302
 
322
303
  # Returns the next or previous page on the same level or nil.
@@ -27,7 +27,7 @@ module Alchemy
27
27
 
28
28
  # Returns true or false if the pages layout_description for config/alchemy/page_layouts.yml contains redirects_to_external: true
29
29
  def redirects_to_external?
30
- !!definition["redirects_to_external"]
30
+ definition["redirects_to_external"]
31
31
  end
32
32
 
33
33
  def has_controller?
@@ -6,7 +6,7 @@ $('#element_<%= @element.id %>').hide(200, function() {
6
6
  $('#element_trash_button .icon').addClass('full');
7
7
  Alchemy.PreviewWindow.refresh();
8
8
  <% @element.contents.essence_richtexts.each do |content| %>
9
- tinymce.get('tinymce_<%= content.id %>').remove();
9
+ tinymce.get('contents_content_<%= content.id %>_body').remove();
10
10
  <% end %>
11
11
  <%= update_essence_select_elements(@page, @element) -%>
12
12
  });
@@ -1,4 +1,4 @@
1
- <li id="page_<%= page.id %>" class="page_level_<%= "#{page.level} #{page.page_layout}" %>" data-slug="<%= page.slug %>" data-restricted="<%= page.restricted? %>" data-visible="<%= page.visible? %>" data-external="<%= page.redirects_to_external? %>">
1
+ <li id="page_<%= page.id %>" class="page_level_<%= "#{page.level} #{page.page_layout}" %>">
2
2
  <div class="sitemap_page<%= page.locked ? ' locked' : '' %>" name="<%= page.name %>">
3
3
  <div class="sitemap_left_images">
4
4
  <%= sitemap_folder_link(page) unless page.level == 1 || page.children.blank? || @sorting %>
@@ -19,6 +19,7 @@ require 'alchemy/essence'
19
19
  require 'alchemy/ferret/search'
20
20
  require 'alchemy/filetypes'
21
21
  require 'alchemy/i18n'
22
+ require 'alchemy/language_helpers'
22
23
  require 'alchemy/logger'
23
24
  require 'alchemy/modules'
24
25
  require 'alchemy/mount_point'
@@ -73,5 +74,9 @@ module Alchemy
73
74
  Alchemy::Auth::Engine.get_instance.load(File.join(File.dirname(__FILE__), '../..', 'config/authorization_rules.rb'))
74
75
  end
75
76
 
77
+ config.to_prepare do
78
+ ApplicationController.send(:include, Alchemy::LanguageHelpers)
79
+ end
80
+
76
81
  end
77
82
  end
@@ -0,0 +1,55 @@
1
+ module Alchemy
2
+ module LanguageHelpers
3
+ def self.included(controller)
4
+ controller.send(:before_filter, :set_language)
5
+ end
6
+
7
+ private
8
+
9
+ # Sets the language for rendering pages in pages controller.
10
+ #
11
+ def set_language(lang = nil)
12
+ if lang
13
+ @language = lang.is_a?(Language) ? lang : load_language_from(lang)
14
+ else
15
+ # find the best language and remember it for later
16
+ @language = load_language_from_params ||
17
+ load_language_from_session ||
18
+ load_language_default
19
+ end
20
+
21
+ # store language in session
22
+ store_language_in_session(@language)
23
+
24
+ # switch locale to selected language
25
+ ::I18n.locale = @language.code
26
+ end
27
+
28
+ def load_language_from_params
29
+ if params[:lang].present?
30
+ Language.find_by_code(params[:lang])
31
+ end
32
+ end
33
+
34
+ def load_language_from_session
35
+ if session[:language_id].present?
36
+ Language.find_by_id(session[:language_id])
37
+ end
38
+ end
39
+
40
+ def load_language_from(language_code_or_id)
41
+ Language.find_by_id(language_code_or_id) || Language.find_by_code(language_code_or_id)
42
+ end
43
+
44
+ def load_language_default
45
+ Language.get_default || raise(DefaultLanguageNotFoundError)
46
+ end
47
+
48
+ def store_language_in_session(language)
49
+ if language && language.id
50
+ session[:language_id] = language.id
51
+ session[:language_code] = language.code
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,7 +1,9 @@
1
1
  module Alchemy
2
- VERSION = "2.7.5"
2
+
3
+ VERSION = "2.8.1"
3
4
 
4
5
  def self.version
5
6
  VERSION
6
7
  end
8
+
7
9
  end
@@ -55,95 +55,6 @@ module Alchemy
55
55
  end
56
56
  end
57
57
 
58
- describe '#order' do
59
- let(:page_1) { FactoryGirl.create(:page, visible: true) }
60
- let(:page_2) { FactoryGirl.create(:page, visible: true) }
61
- let(:page_3) { FactoryGirl.create(:page, visible: true) }
62
- let(:page_item_1) { {id: page_1.id, slug: page_1.slug, restricted: false, external: page_1.redirects_to_external?, visible: page_1.visible?, children: [page_item_2]} }
63
- let(:page_item_2) { {id: page_2.id, slug: page_2.slug, restricted: false, external: page_2.redirects_to_external?, visible: page_2.visible?, children: [page_item_3]} }
64
- let(:page_item_3) { {id: page_3.id, slug: page_3.slug, restricted: false, external: page_3.redirects_to_external?, visible: page_3.visible? } }
65
- let(:set_of_pages) { [page_item_1] }
66
-
67
- it "stores the new order" do
68
- xhr :post, :order, set: set_of_pages.to_json
69
- page_1.reload
70
- expect(page_1.descendants).to eq([page_2, page_3])
71
- end
72
-
73
- context 'with url nesting enabled' do
74
- before { Alchemy::Config.stub(get: true) }
75
-
76
- it "updates the pages urlnames" do
77
- xhr :post, :order, set: set_of_pages.to_json
78
- [page_1, page_2, page_3].map(&:reload)
79
- expect(page_1.urlname).to eq("#{page_1.slug}")
80
- expect(page_2.urlname).to eq("#{page_1.slug}/#{page_2.slug}")
81
- expect(page_3.urlname).to eq("#{page_1.slug}/#{page_2.slug}/#{page_3.slug}")
82
- end
83
-
84
- context 'with invisible page in tree' do
85
- let(:page_item_2) do
86
- {
87
- id: page_2.id,
88
- slug: page_2.slug,
89
- children: [page_item_3],
90
- visible: false
91
- }
92
- end
93
-
94
- it "does not use this pages slug in urlnames of descendants" do
95
- xhr :post, :order, set: set_of_pages.to_json
96
- [page_1, page_2, page_3].map(&:reload)
97
- expect(page_1.urlname).to eq("#{page_1.slug}")
98
- expect(page_2.urlname).to eq("#{page_1.slug}/#{page_2.slug}")
99
- expect(page_3.urlname).to eq("#{page_1.slug}/#{page_3.slug}")
100
- end
101
- end
102
-
103
- context 'with external page in tree' do
104
- let(:page_item_2) do
105
- {
106
- id: page_2.id,
107
- slug: page_2.slug,
108
- children: [page_item_3],
109
- external: true
110
- }
111
- end
112
-
113
- it "does not use this pages slug in urlnames of descendants" do
114
- xhr :post, :order, set: set_of_pages.to_json
115
- [page_1, page_2, page_3].map(&:reload)
116
- expect(page_3.urlname).to eq("#{page_1.slug}/#{page_3.slug}")
117
- end
118
- end
119
-
120
- context 'with restricted page in tree' do
121
- let(:page_2) { FactoryGirl.create(:page, restricted: true) }
122
- let(:page_item_2) do
123
- {
124
- id: page_2.id,
125
- slug: page_2.slug,
126
- children: [page_item_3],
127
- restricted: true
128
- }
129
- end
130
-
131
- it "updates restricted status of descendants" do
132
- xhr :post, :order, set: set_of_pages.to_json
133
- page_3.reload
134
- expect(page_3.restricted).to be_true
135
- end
136
- end
137
-
138
- it "creates legacy urls" do
139
- xhr :post, :order, set: set_of_pages.to_json
140
- [page_2, page_3].map(&:reload)
141
- expect(page_2.legacy_urls.size).to eq(1)
142
- expect(page_3.legacy_urls.size).to eq(1)
143
- end
144
- end
145
- end
146
-
147
58
  describe "#configure" do
148
59
  render_views
149
60
 
@@ -1117,124 +1117,6 @@ module Alchemy
1117
1117
  end
1118
1118
  end
1119
1119
 
1120
- describe "#update_node!" do
1121
-
1122
- let(:original_url) { "sample-url" }
1123
- let(:page) { FactoryGirl.create(:page, :language => language, :parent_id => language_root.id, :urlname => original_url, restricted: false) }
1124
- let(:node) { TreeNode.new(10, 11, 12, 13, "another-url", true) }
1125
-
1126
- context "when nesting is enabled" do
1127
- before { Alchemy::Config.stub(:get).with(:url_nesting) { true } }
1128
-
1129
- context "when page is not external" do
1130
-
1131
- before { page.stub(redirects_to_external?: false)}
1132
-
1133
- it "should update all attributes" do
1134
- page.update_node!(node)
1135
- page.reload
1136
- expect(page.lft).to eq(node.left)
1137
- expect(page.rgt).to eq(node.right)
1138
- expect(page.parent_id).to eq(node.parent)
1139
- expect(page.depth).to eq(node.depth)
1140
- expect(page.urlname).to eq(node.url)
1141
- expect(page.restricted).to eq(node.restricted)
1142
- end
1143
-
1144
- context "when url is the same" do
1145
- let(:node) { TreeNode.new(10, 11, 12, 13, original_url, true) }
1146
-
1147
- it "should not create a legacy url" do
1148
- page.update_node!(node)
1149
- page.reload
1150
- expect(page.legacy_urls.size).to eq(0)
1151
- end
1152
- end
1153
-
1154
- context "when url is not the same" do
1155
- it "should create a legacy url" do
1156
- page.update_node!(node)
1157
- page.reload
1158
- expect(page.legacy_urls.size).to eq(1)
1159
- end
1160
- end
1161
- end
1162
-
1163
- context "when page is external" do
1164
-
1165
- before { page.stub(redirects_to_external?: true) }
1166
-
1167
- it "should update all attributes except url" do
1168
- page.update_node!(node)
1169
- page.reload
1170
- expect(page.lft).to eq(node.left)
1171
- expect(page.rgt).to eq(node.right)
1172
- expect(page.parent_id).to eq(node.parent)
1173
- expect(page.depth).to eq(node.depth)
1174
- expect(page.urlname).to eq(original_url)
1175
- expect(page.restricted).to eq(node.restricted)
1176
- end
1177
-
1178
- it "should not create a legacy url" do
1179
- page.update_node!(node)
1180
- page.reload
1181
- expect(page.legacy_urls.size).to eq(0)
1182
- end
1183
- end
1184
- end
1185
-
1186
- context "when nesting is disabled" do
1187
- before { Alchemy::Config.stub(:get).with(:url_nesting) { false } }
1188
-
1189
- context "when page is not external" do
1190
-
1191
- before { page.stub(redirects_to_external?: false)}
1192
-
1193
- it "should update all attributes except url" do
1194
- page.update_node!(node)
1195
- page.reload
1196
- expect(page.lft).to eq(node.left)
1197
- expect(page.rgt).to eq(node.right)
1198
- expect(page.parent_id).to eq(node.parent)
1199
- expect(page.depth).to eq(node.depth)
1200
- expect(page.urlname).to eq(original_url)
1201
- expect(page.restricted).to eq(node.restricted)
1202
- end
1203
-
1204
- it "should not create a legacy url" do
1205
- page.update_node!(node)
1206
- page.reload
1207
- expect(page.legacy_urls.size).to eq(0)
1208
- end
1209
-
1210
- end
1211
-
1212
- context "when page is external" do
1213
-
1214
- before { page.stub(redirects_to_external?: true) }
1215
-
1216
- before { Alchemy::Config.stub(get: true) }
1217
-
1218
- it "should update all attributes except url" do
1219
- page.update_node!(node)
1220
- page.reload
1221
- expect(page.lft).to eq(node.left)
1222
- expect(page.rgt).to eq(node.right)
1223
- expect(page.parent_id).to eq(node.parent)
1224
- expect(page.depth).to eq(node.depth)
1225
- expect(page.urlname).to eq(original_url)
1226
- expect(page.restricted).to eq(node.restricted)
1227
- end
1228
-
1229
- it "should not create a legacy url" do
1230
- page.update_node!(node)
1231
- page.reload
1232
- expect(page.legacy_urls.size).to eq(0)
1233
- end
1234
- end
1235
- end
1236
- end
1237
-
1238
1120
  describe '#slug' do
1239
1121
  context "with parents path saved in urlname" do
1240
1122
  let(:page) { FactoryGirl.build(:page, urlname: 'root/parent/my-name')}
data/spec/spec_helper.rb CHANGED
@@ -33,11 +33,6 @@ Capybara.default_selector = :css
33
33
  Capybara.register_driver(:rack_test_translated_header) do |app|
34
34
  Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_ACCEPT_LANGUAGE' => 'de' })
35
35
  end
36
- if ENV['CI']
37
- Capybara.register_driver :poltergeist do |app|
38
- Capybara::Poltergeist::Driver.new(app, timeout: 60)
39
- end
40
- end
41
36
  Capybara.javascript_driver = :poltergeist
42
37
 
43
38
  # Load support files
@@ -53,32 +48,15 @@ RSpec.configure do |config|
53
48
  config.include Devise::TestHelpers, :type => :controller
54
49
  config.include Alchemy::Specs::ControllerHelpers, :type => :controller
55
50
  config.include Alchemy::Specs::IntegrationHelpers, :type => :feature
56
- config.use_transactional_fixtures = false
57
-
51
+ config.use_transactional_fixtures = true
52
+ # Make sure the database is clean and ready for test
58
53
  config.before(:suite) do
59
- DatabaseCleaner.clean_with(:truncation)
54
+ truncate_all_tables
60
55
  Alchemy::Seeder.seed!
61
56
  end
62
-
63
- # All specs are running in transactions, but feature specs not.
57
+ # Ensuring that the locale is always resetted to :en before running any tests
64
58
  config.before(:each) do
65
59
  Alchemy::Site.current = nil
66
60
  ::I18n.locale = :en
67
- if example.metadata[:type] == :feature
68
- DatabaseCleaner.strategy = :truncation
69
- else
70
- DatabaseCleaner.strategy = :transaction
71
- end
72
- DatabaseCleaner.start
73
- end
74
-
75
- # After each spec the database gets cleaned. (via rollback or truncate for feature specs)
76
- # After every feature spec the database gets seeded so the next spec can rely on that data.
77
- config.append_after(:each) do
78
- DatabaseCleaner.clean
79
- if example.metadata[:type] == :feature
80
- Alchemy::Seeder.stub(:puts)
81
- Alchemy::Seeder.seed!
82
- end
83
61
  end
84
62
  end
@@ -60,20 +60,6 @@ module Alchemy
60
60
  FactoryGirl.create(:admin_user)
61
61
  end
62
62
 
63
- # Capybara actions to create a new element.
64
- #
65
- # You can pass the name of the desired element, or just use the default "Article".
66
- #
67
- def create_element!(name = 'Article')
68
- within '.alchemy-elements-window' do
69
- click_link Alchemy::I18n.t('New Element')
70
- end
71
- within '.new_alchemy_element' do
72
- select(name, from: 'element[name]')
73
- click_button 'Add'
74
- end
75
- end
76
-
77
63
  end
78
64
 
79
65
  end
@@ -0,0 +1,31 @@
1
+ # https://gist.github.com/mperham/3049152
2
+ # Fixes Capybara database connection issues
3
+ class ActiveRecord::Base
4
+ mattr_accessor :shared_connection
5
+ @@shared_connection = nil
6
+
7
+ def self.connection
8
+ @@shared_connection || ConnectionPool::Wrapper.new(:size => 1) { retrieve_connection }
9
+ end
10
+ end
11
+ ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
12
+
13
+ # fast truncation of all tables that need truncations (select is 10x faster then truncate)
14
+ # http://grosser.it/2012/07/03/rubyactiverecord-fastest-way-to-truncate-test-database/
15
+ def truncate_all_tables
16
+ config = ActiveRecord::Base.configurations[::Rails.env]
17
+ connection = ActiveRecord::Base.connection
18
+ connection.disable_referential_integrity do
19
+ connection.tables.each do |table_name|
20
+ next if connection.select_value("SELECT count(*) FROM #{table_name}") == 0
21
+ case config["adapter"]
22
+ when "mysql2", "postgresql"
23
+ connection.execute("TRUNCATE #{table_name}")
24
+ when "sqlite3"
25
+ connection.execute("DELETE FROM #{table_name}")
26
+ connection.execute("DELETE FROM sqlite_sequence where name='#{table_name}'")
27
+ end
28
+ end
29
+ connection.execute("VACUUM") if config["adapter"] == "sqlite3"
30
+ end
31
+ end
@@ -255,14 +255,8 @@
255
255
 
256
256
  function _recursiveItems(li) {
257
257
  var id = ($(li).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
258
-
259
- var restricted = $(li).data("restricted");
260
- var slug = $(li).data("slug");
261
- var external = $(li).data("external");
262
- var visible = $(li).data("visible");
263
-
264
258
  if (id) {
265
- var item = {"id": id[2], "slug": slug, "restricted": restricted, "external": external, "visible": visible};
259
+ var item = {"id":id[2]};
266
260
  if ($(li).children(o.listType).children('li').length > 0) {
267
261
  item.children = [];
268
262
  $(li).children(o.listType).children('li').each(function () {
@@ -397,4 +391,4 @@
397
391
  }));
398
392
 
399
393
  $.ui.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.ui.nestedSortable.prototype.options);
400
- })(jQuery);
394
+ })(jQuery);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.5
4
+ version: 2.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas von Deyen
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2014-06-12 00:00:00.000000000 Z
15
+ date: 2014-04-23 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rails
@@ -551,7 +551,6 @@ files:
551
551
  - app/models/alchemy/site.rb
552
552
  - app/models/alchemy/site/layout.rb
553
553
  - app/models/alchemy/tag.rb
554
- - app/models/alchemy/tree_node.rb
555
554
  - app/models/alchemy/user.rb
556
555
  - app/sweepers/alchemy/content_sweeper.rb
557
556
  - app/sweepers/alchemy/pages_sweeper.rb
@@ -787,6 +786,7 @@ files:
787
786
  - lib/alchemy/filetypes.rb
788
787
  - lib/alchemy/i18n.rb
789
788
  - lib/alchemy/kaminari/scoped_pagination_url_helper.rb
789
+ - lib/alchemy/language_helpers.rb
790
790
  - lib/alchemy/logger.rb
791
791
  - lib/alchemy/modules.rb
792
792
  - lib/alchemy/mount_point.rb
@@ -918,8 +918,6 @@ files:
918
918
  - spec/dummy/public/stylesheets/.gitkeep
919
919
  - spec/dummy/script/rails
920
920
  - spec/fast_specs.rb
921
- - spec/features/admin/element_create_feature_spec.rb
922
- - spec/features/admin/element_trash_feature_spec.rb
923
921
  - spec/features/admin/link_overlay_spec.rb
924
922
  - spec/features/admin/modules_integration_spec.rb
925
923
  - spec/features/admin/pages_controller_spec.rb
@@ -991,6 +989,7 @@ files:
991
989
  - spec/support/alchemy/controller_hacks.rb
992
990
  - spec/support/alchemy/controller_helpers.rb
993
991
  - spec/support/alchemy/integration_helpers.rb
992
+ - spec/support/alchemy/test_tweaks.rb
994
993
  - spec/support/ci/install_phantomjs
995
994
  - spec/support/factories.rb
996
995
  - spec/support/image with spaces.png
@@ -1211,8 +1210,6 @@ test_files:
1211
1210
  - spec/dummy/public/stylesheets/.gitkeep
1212
1211
  - spec/dummy/script/rails
1213
1212
  - spec/fast_specs.rb
1214
- - spec/features/admin/element_create_feature_spec.rb
1215
- - spec/features/admin/element_trash_feature_spec.rb
1216
1213
  - spec/features/admin/link_overlay_spec.rb
1217
1214
  - spec/features/admin/modules_integration_spec.rb
1218
1215
  - spec/features/admin/pages_controller_spec.rb
@@ -1284,6 +1281,7 @@ test_files:
1284
1281
  - spec/support/alchemy/controller_hacks.rb
1285
1282
  - spec/support/alchemy/controller_helpers.rb
1286
1283
  - spec/support/alchemy/integration_helpers.rb
1284
+ - spec/support/alchemy/test_tweaks.rb
1287
1285
  - spec/support/ci/install_phantomjs
1288
1286
  - spec/support/factories.rb
1289
1287
  - spec/support/image with spaces.png
@@ -1,4 +0,0 @@
1
- module Alchemy
2
- class TreeNode < Struct.new(:left, :right, :parent, :depth, :url, :restricted)
3
- end
4
- end
@@ -1,18 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'element create feature', js: true do
4
- let(:a_page) { FactoryGirl.create(:page) }
5
-
6
- before do
7
- authorize_as_admin
8
- visit edit_admin_page_path(a_page)
9
- expect(page).to have_no_selector('.alchemy-elements-window .element_editor')
10
- end
11
-
12
- it "adds a new element to the list" do
13
- create_element!
14
- expect(page).to have_no_selector(".spinner") # wait until spinner disappears
15
- expect(page).to have_selector(".element_editor", count: 1)
16
- end
17
- end
18
-
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "element trash feature", js: true do
4
- let(:a_page) { FactoryGirl.create(:page) }
5
-
6
- before do
7
- authorize_as_admin
8
- visit edit_admin_page_path(a_page)
9
- create_element! # We want to trash an article element later because it contains a richtext essence
10
- expect(page).to have_no_selector(".spinner") # wait until spinner disappears
11
- end
12
-
13
- it "removes an element from the list" do
14
- expect(page).to have_selector(".element_editor", count: 1)
15
- within ".alchemy-elements-window .element_editor:first" do
16
- click_link Alchemy::I18n.t("trash element")
17
- end
18
- expect(page).to have_content Alchemy::I18n.t('Element trashed')
19
- expect(page).to have_no_selector(".element_editor")
20
- end
21
- end